@visactor/vtable-plugins 1.22.4-alpha.2 → 1.22.4
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.
- package/cjs/auto-fill/rules.js +2 -1
- package/cjs/contextmenu/menu-manager.js +1 -2
- package/cjs/filter/condition-filter.d.ts +1 -3
- package/cjs/filter/condition-filter.js +20 -20
- package/cjs/filter/condition-filter.js.map +1 -1
- package/cjs/filter/filter-state-manager.d.ts +0 -14
- package/cjs/filter/filter-state-manager.js +1 -35
- package/cjs/filter/filter-state-manager.js.map +1 -1
- package/cjs/filter/filter-toolbar.d.ts +5 -4
- package/cjs/filter/filter-toolbar.js +30 -30
- package/cjs/filter/filter-toolbar.js.map +1 -1
- package/cjs/filter/filter.d.ts +4 -3
- package/cjs/filter/filter.js +15 -19
- package/cjs/filter/filter.js.map +1 -1
- package/cjs/filter/styles.d.ts +124 -2
- package/cjs/filter/styles.js.map +1 -1
- package/cjs/filter/types.d.ts +0 -27
- package/cjs/filter/types.js.map +1 -1
- package/cjs/filter/value-filter.d.ts +1 -5
- package/cjs/filter/value-filter.js +118 -145
- package/cjs/filter/value-filter.js.map +1 -1
- package/cjs/gantt-export-image.d.ts +0 -1
- package/cjs/gantt-export-image.js +2 -10
- package/cjs/gantt-export-image.js.map +1 -1
- package/cjs/master-detail-plugin/config.js +2 -2
- package/cjs/master-detail-plugin/config.js.map +1 -1
- package/cjs/table-export/csv/index.js +1 -1
- package/cjs/table-export/csv/index.js.map +1 -1
- package/dist/vtable-plugins.js +211 -9794
- package/dist/vtable-plugins.min.js +3 -3
- package/es/auto-fill/rules.js +2 -1
- package/es/contextmenu/menu-manager.js +1 -2
- package/es/filter/condition-filter.d.ts +1 -3
- package/es/filter/condition-filter.js +14 -14
- package/es/filter/condition-filter.js.map +1 -1
- package/es/filter/filter-state-manager.d.ts +0 -14
- package/es/filter/filter-state-manager.js +1 -35
- package/es/filter/filter-state-manager.js.map +1 -1
- package/es/filter/filter-toolbar.d.ts +5 -4
- package/es/filter/filter-toolbar.js +28 -29
- package/es/filter/filter-toolbar.js.map +1 -1
- package/es/filter/filter.d.ts +4 -3
- package/es/filter/filter.js +13 -21
- package/es/filter/filter.js.map +1 -1
- package/es/filter/styles.d.ts +124 -2
- package/es/filter/styles.js.map +1 -1
- package/es/filter/types.d.ts +0 -27
- package/es/filter/types.js.map +1 -1
- package/es/filter/value-filter.d.ts +1 -5
- package/es/filter/value-filter.js +118 -145
- package/es/filter/value-filter.js.map +1 -1
- package/es/gantt-export-image.d.ts +0 -1
- package/es/gantt-export-image.js +1 -11
- package/es/gantt-export-image.js.map +1 -1
- package/es/master-detail-plugin/config.js +2 -2
- package/es/master-detail-plugin/config.js.map +1 -1
- package/es/table-export/csv/index.js +1 -1
- package/es/table-export/csv/index.js.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/gantt-export-image.ts"],"names":[],"mappings":"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","file":"gantt-export-image.js","sourcesContent":["/**\r\n * 这个文件提供了甘特图导出功能,但使用了懒加载方式避免强制依赖\r\n * 只有在实际使用时才会尝试加载 @visactor/vtable-gantt\r\n */\r\nimport { vglobal } from '@visactor/vtable/es/vrender';\r\n// 使用类型声明而不是直接导入,避免静态依赖\r\ntype Gantt = any;\r\ninterface IGanttPlugin {\r\n id: string;\r\n name: string;\r\n run: (...args: any[]) => void;\r\n release?: () => void;\r\n}\r\n\r\n// 甘特图导出配置项接口\r\nexport interface ExportOptions {\r\n fileName?: string;\r\n type?: 'png' | 'jpeg';\r\n quality?: number;\r\n backgroundColor?: string;\r\n scale?: number;\r\n download?: boolean;\r\n}\r\n\r\n// 检查依赖是否可用\r\nconst checkGanttDependency = () => {\r\n try {\r\n // 不实际导入,只检查是否可用\r\n require.resolve('@visactor/vtable-gantt');\r\n return true;\r\n } catch (e) {\r\n console.warn(\r\n '警告: 使用 ExportGanttPlugin 需要安装 @visactor/vtable-gantt 依赖。\\n' +\r\n '请执行: npm install @visactor/vtable-gantt\\n' +\r\n '更多信息请参考文档: https://visactor.io/vtable'\r\n );\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * 甘特图导出插件\r\n * @description 提供完整的甘特图导出功能,支持高分辨率输出和精准布局保留\r\n */\r\nexport class ExportGanttPlugin implements IGanttPlugin {\r\n id: string = `gantt-export-helper`;\r\n name = 'Gantt Export Helper';\r\n private _gantt: Gantt | null = null;\r\n\r\n constructor() {\r\n // 构造时提前检查依赖可用性,以便给开发者更早的反馈\r\n checkGanttDependency();\r\n }\r\n\r\n // run 方法,在插件初始化时由 PluginManager调用\r\n run(...args: any[]): void {\r\n const ganttInstance = args[0] as Gantt;\r\n if (!ganttInstance) {\r\n console.error('ExportGanttPlugin: Gantt instance not provided to run method.');\r\n return;\r\n }\r\n this._gantt = ganttInstance;\r\n }\r\n /**\r\n * 执行甘特图导出操作\r\n * @async\r\n * @param {ExportOptions} [options={}] 导出配置选项\r\n * @returns {Promise<string | undefined>} 返回Base64格式的图片数据,或在未初始化时返回 undefined\r\n * @throws {Error} 导出过程中发生错误时抛出异常\r\n */\r\n async exportToImage(options: ExportOptions = {}): Promise<string | undefined> {\r\n // 初始检查依赖是否存在\r\n if (!checkGanttDependency()) {\r\n return undefined;\r\n }\r\n\r\n if (!this._gantt) {\r\n // 保留这个 error\r\n console.error('ExportGanttPlugin: Gantt instance not available.');\r\n return undefined;\r\n }\r\n\r\n const {\r\n fileName = 'gantt-export',\r\n type = 'png',\r\n quality = 1,\r\n backgroundColor = '#ffffff',\r\n scale = window.devicePixelRatio || 1,\r\n download = true // 默认执行下载\r\n } = options;\r\n\r\n try {\r\n const { tempContainer, clonedGantt } = await this.createFullSizeContainer(scale);\r\n\r\n try {\r\n await new Promise(resolve => vglobal.getRequestAnimationFrame()(resolve));\r\n\r\n const totalWidth =\r\n (clonedGantt.taskListTableInstance.getAllColsWidth() + clonedGantt.getAllDateColsWidth()) * scale;\r\n const totalHeight = clonedGantt.getAllRowsHeight() * scale;\r\n\r\n const exportCanvas = document.createElement('canvas');\r\n exportCanvas.width = totalWidth;\r\n exportCanvas.height = totalHeight;\r\n const ctx = exportCanvas.getContext('2d')!;\r\n\r\n ctx.fillStyle = backgroundColor;\r\n ctx.fillRect(0, 0, totalWidth, totalHeight);\r\n\r\n if (clonedGantt.taskListTableInstance?.canvas) {\r\n ctx.drawImage(\r\n clonedGantt.taskListTableInstance.canvas,\r\n 0,\r\n 0,\r\n clonedGantt.taskListTableInstance.getAllColsWidth() * scale,\r\n totalHeight\r\n );\r\n }\r\n\r\n const splitLineWidth = 3 * scale;\r\n const splitLineX = clonedGantt.taskListTableInstance.getAllColsWidth() * scale;\r\n ctx.fillStyle = 'rgb(225, 228, 232)';\r\n ctx.fillRect(splitLineX - splitLineWidth / 2, 0, splitLineWidth, totalHeight);\r\n\r\n const sourceX = 4 * scale;\r\n const sourceWidth = clonedGantt.canvas.width - sourceX;\r\n\r\n if (clonedGantt.canvas) {\r\n ctx.drawImage(\r\n clonedGantt.canvas,\r\n sourceX,\r\n 0,\r\n sourceWidth,\r\n clonedGantt.canvas.height,\r\n (clonedGantt.taskListTableInstance.getAllColsWidth() + 1.5) * scale,\r\n 0,\r\n (clonedGantt.getAllDateColsWidth() - 1.5) * scale,\r\n totalHeight\r\n );\r\n }\r\n\r\n return this.finalizeExport(exportCanvas, fileName, type, quality, download);\r\n } finally {\r\n tempContainer.remove();\r\n // 确保克隆的甘特图实例被释放\r\n clonedGantt.release();\r\n }\r\n } catch (error) {\r\n console.error('[Gantt Export Plugin] Export failed:', error);\r\n throw new Error(`甘特图导出失败: ${error instanceof Error ? error.message : '未知错误'}`);\r\n }\r\n }\r\n\r\n /**\r\n * 获取甘特图的 Base64 图片数据,不触发下载\r\n * @async\r\n * @param {Omit<ExportOptions, 'download'>} [options={}] 导出配置选项(不包含 download 参数)\r\n * @returns {Promise<string | undefined>} 返回 Base64 格式的图片数据,或在未初始化时返回 undefined\r\n * @throws {Error} 导出过程中发生错误时抛出异常\r\n */\r\n async exportToBase64(options: Omit<ExportOptions, 'download'> = {}): Promise<string | undefined> {\r\n // 调用 exportToImage 方法,但设置 download 为 false\r\n return this.exportToImage({\r\n ...options,\r\n download: false\r\n });\r\n }\r\n\r\n private async createFullSizeContainer(scale: number) {\r\n if (!this._gantt) {\r\n // 保留这个 error\r\n throw new Error('ExportGanttPlugin: Gantt instance not available to create container.');\r\n }\r\n\r\n const tempContainer = document.createElement('div');\r\n tempContainer.style.position = 'fixed';\r\n tempContainer.style.left = '-9999px';\r\n tempContainer.style.overflow = 'hidden';\r\n tempContainer.style.width = `${window.innerWidth + 100}px`;\r\n tempContainer.style.height = `${window.innerHeight + 100}px`;\r\n document.body.appendChild(tempContainer);\r\n\r\n const clonedContainer = document.createElement('div');\r\n\r\n const totalWidth = this._gantt.taskListTableInstance.getAllColsWidth() + this._gantt.getAllDateColsWidth();\r\n const totalHeight = this._gantt.getAllRowsHeight();\r\n\r\n clonedContainer.style.width = `${totalWidth}px`;\r\n clonedContainer.style.height = `${totalHeight}px`;\r\n tempContainer.appendChild(clonedContainer);\r\n\r\n try {\r\n // 动态导入甘特图组件\r\n let GanttClass;\r\n try {\r\n const module = await import('@visactor/vtable-gantt');\r\n GanttClass = module.Gantt;\r\n if (!GanttClass) {\r\n throw new Error('Gantt class not found in @visactor/vtable-gantt');\r\n }\r\n } catch (err) {\r\n console.error('无法加载甘特图组件:', err);\r\n throw new Error(\r\n '导出甘特图需要安装并正确加载 @visactor/vtable-gantt 依赖\\n' + '请执行: npm install @visactor/vtable-gantt'\r\n );\r\n }\r\n\r\n const clonedGantt = new GanttClass(clonedContainer, {\r\n ...this._gantt.options,\r\n records: this._gantt.records,\r\n taskListTable: {\r\n ...this._gantt.options.taskListTable,\r\n tableWidth: undefined as unknown as number,\r\n minTableWidth: undefined as unknown as number,\r\n maxTableWidth: undefined as unknown as number\r\n },\r\n plugins: []\r\n });\r\n\r\n clonedGantt.setPixelRatio(scale);\r\n\r\n // 禁用裁剪\r\n if ((clonedGantt as any).scenegraph?.ganttGroup) {\r\n (clonedGantt as any).scenegraph.ganttGroup.setAttribute('clip', false);\r\n }\r\n if ((clonedGantt.taskListTableInstance as any)?.scenegraph?.tableGroup) {\r\n (clonedGantt.taskListTableInstance as any).scenegraph.tableGroup.setAttribute('clip', false);\r\n }\r\n\r\n clonedGantt.scenegraph.stage.render();\r\n\r\n return { tempContainer, clonedGantt };\r\n } catch (err) {\r\n // 清理创建的DOM元素\r\n if (tempContainer && tempContainer.parentNode) {\r\n tempContainer.remove();\r\n }\r\n console.error('无法导入甘特图组件,请确保已安装 @visactor/vtable-gantt 依赖', err);\r\n throw new Error('导出甘特图需要安装 @visactor/vtable-gantt 依赖');\r\n }\r\n }\r\n private finalizeExport(\r\n canvas: HTMLCanvasElement,\r\n fileName: string,\r\n type: string,\r\n quality: number,\r\n download: boolean = true\r\n ): string {\r\n const base64 = canvas.toDataURL(`image/${type}`, quality);\r\n\r\n // 如果需要下载,则创建下载链接\r\n if (download) {\r\n const link = document.createElement('a');\r\n link.download = `${fileName}.${type}`;\r\n link.href = base64;\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n }\r\n\r\n return base64;\r\n }\r\n\r\n release(): void {\r\n this._gantt = null;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/gantt-export-image.ts"],"names":[],"mappings":"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","file":"gantt-export-image.js","sourcesContent":["/**\r\n * 这个文件提供了甘特图导出功能,但使用了懒加载方式避免强制依赖\r\n * 只有在实际使用时才会尝试加载 @visactor/vtable-gantt\r\n */\r\nimport { vglobal } from '@visactor/vtable/es/vrender';\r\n// 使用类型声明而不是直接导入,避免静态依赖\r\ntype Gantt = any;\r\ninterface IGanttPlugin {\r\n id: string;\r\n name: string;\r\n run: (...args: any[]) => void;\r\n release?: () => void;\r\n}\r\n\r\n// 甘特图导出配置项接口\r\nexport interface ExportOptions {\r\n fileName?: string;\r\n type?: 'png' | 'jpeg';\r\n quality?: number;\r\n backgroundColor?: string;\r\n scale?: number;\r\n download?: boolean;\r\n}\r\n\r\n\r\n/**\r\n * 甘特图导出插件\r\n * @description 提供完整的甘特图导出功能,支持高分辨率输出和精准布局保留\r\n */\r\nexport class ExportGanttPlugin implements IGanttPlugin {\r\n id: string = `gantt-export-helper`;\r\n name = 'Gantt Export Helper';\r\n private _gantt: Gantt | null = null;\r\n\r\n // run 方法,在插件初始化时由 PluginManager调用\r\n run(...args: any[]): void {\r\n const ganttInstance = args[0] as Gantt;\r\n if (!ganttInstance) {\r\n console.error('ExportGanttPlugin: Gantt instance not provided to run method.');\r\n return;\r\n }\r\n this._gantt = ganttInstance;\r\n }\r\n /**\r\n * 执行甘特图导出操作\r\n * @async\r\n * @param {ExportOptions} [options={}] 导出配置选项\r\n * @returns {Promise<string | undefined>} 返回Base64格式的图片数据,或在未初始化时返回 undefined\r\n * @throws {Error} 导出过程中发生错误时抛出异常\r\n */\r\n async exportToImage(options: ExportOptions = {}): Promise<string | undefined> {\r\n\r\n if (!this._gantt) {\r\n // 保留这个 error\r\n console.error('ExportGanttPlugin: Gantt instance not available.');\r\n return undefined;\r\n }\r\n\r\n const {\r\n fileName = 'gantt-export',\r\n type = 'png',\r\n quality = 1,\r\n backgroundColor = '#ffffff',\r\n scale = window.devicePixelRatio || 1,\r\n download = true // 默认执行下载\r\n } = options;\r\n\r\n try {\r\n const { tempContainer, clonedGantt } = await this.createFullSizeContainer(scale);\r\n\r\n try {\r\n await new Promise(resolve => vglobal.getRequestAnimationFrame()(resolve));\r\n\r\n const totalWidth =\r\n (clonedGantt.taskListTableInstance.getAllColsWidth() + clonedGantt.getAllDateColsWidth()) * scale;\r\n const totalHeight = clonedGantt.getAllRowsHeight() * scale;\r\n\r\n const exportCanvas = document.createElement('canvas');\r\n exportCanvas.width = totalWidth;\r\n exportCanvas.height = totalHeight;\r\n const ctx = exportCanvas.getContext('2d')!;\r\n\r\n ctx.fillStyle = backgroundColor;\r\n ctx.fillRect(0, 0, totalWidth, totalHeight);\r\n\r\n if (clonedGantt.taskListTableInstance?.canvas) {\r\n ctx.drawImage(\r\n clonedGantt.taskListTableInstance.canvas,\r\n 0,\r\n 0,\r\n clonedGantt.taskListTableInstance.getAllColsWidth() * scale,\r\n totalHeight\r\n );\r\n }\r\n\r\n const splitLineWidth = 3 * scale;\r\n const splitLineX = clonedGantt.taskListTableInstance.getAllColsWidth() * scale;\r\n ctx.fillStyle = 'rgb(225, 228, 232)';\r\n ctx.fillRect(splitLineX - splitLineWidth / 2, 0, splitLineWidth, totalHeight);\r\n\r\n const sourceX = 4 * scale;\r\n const sourceWidth = clonedGantt.canvas.width - sourceX;\r\n\r\n if (clonedGantt.canvas) {\r\n ctx.drawImage(\r\n clonedGantt.canvas,\r\n sourceX,\r\n 0,\r\n sourceWidth,\r\n clonedGantt.canvas.height,\r\n (clonedGantt.taskListTableInstance.getAllColsWidth() + 1.5) * scale,\r\n 0,\r\n (clonedGantt.getAllDateColsWidth() - 1.5) * scale,\r\n totalHeight\r\n );\r\n }\r\n\r\n return this.finalizeExport(exportCanvas, fileName, type, quality, download);\r\n } finally {\r\n tempContainer.remove();\r\n // 确保克隆的甘特图实例被释放\r\n clonedGantt.release();\r\n }\r\n } catch (error) {\r\n console.error('[Gantt Export Plugin] Export failed:', error);\r\n throw new Error(`甘特图导出失败: ${error instanceof Error ? error.message : '未知错误'}`);\r\n }\r\n }\r\n\r\n /**\r\n * 获取甘特图的 Base64 图片数据,不触发下载\r\n * @async\r\n * @param {Omit<ExportOptions, 'download'>} [options={}] 导出配置选项(不包含 download 参数)\r\n * @returns {Promise<string | undefined>} 返回 Base64 格式的图片数据,或在未初始化时返回 undefined\r\n * @throws {Error} 导出过程中发生错误时抛出异常\r\n */\r\n async exportToBase64(options: Omit<ExportOptions, 'download'> = {}): Promise<string | undefined> {\r\n // 调用 exportToImage 方法,但设置 download 为 false\r\n return this.exportToImage({\r\n ...options,\r\n download: false\r\n });\r\n }\r\n\r\n private async createFullSizeContainer(scale: number) {\r\n if (!this._gantt) {\r\n // 保留这个 error\r\n throw new Error('ExportGanttPlugin: Gantt instance not available to create container.');\r\n }\r\n\r\n const tempContainer = document.createElement('div');\r\n tempContainer.style.position = 'fixed';\r\n tempContainer.style.left = '-9999px';\r\n tempContainer.style.overflow = 'hidden';\r\n tempContainer.style.width = `${window.innerWidth + 100}px`;\r\n tempContainer.style.height = `${window.innerHeight + 100}px`;\r\n document.body.appendChild(tempContainer);\r\n\r\n const clonedContainer = document.createElement('div');\r\n\r\n const totalWidth = this._gantt.taskListTableInstance.getAllColsWidth() + this._gantt.getAllDateColsWidth();\r\n const totalHeight = this._gantt.getAllRowsHeight();\r\n\r\n clonedContainer.style.width = `${totalWidth}px`;\r\n clonedContainer.style.height = `${totalHeight}px`;\r\n tempContainer.appendChild(clonedContainer);\r\n\r\n try {\r\n // 动态导入甘特图组件\r\n let GanttClass;\r\n try {\r\n const module = await import('@visactor/vtable-gantt');\r\n GanttClass = module.Gantt;\r\n if (!GanttClass) {\r\n throw new Error('Gantt class not found in @visactor/vtable-gantt');\r\n }\r\n } catch (err) {\r\n console.error('无法加载甘特图组件:', err);\r\n throw new Error(\r\n '导出甘特图需要安装并正确加载 @visactor/vtable-gantt 依赖\\n' + '请执行: npm install @visactor/vtable-gantt'\r\n );\r\n }\r\n\r\n const clonedGantt = new GanttClass(clonedContainer, {\r\n ...this._gantt.options,\r\n records: this._gantt.records,\r\n taskListTable: {\r\n ...this._gantt.options.taskListTable,\r\n tableWidth: undefined as unknown as number,\r\n minTableWidth: undefined as unknown as number,\r\n maxTableWidth: undefined as unknown as number\r\n },\r\n plugins: []\r\n });\r\n\r\n clonedGantt.setPixelRatio(scale);\r\n\r\n // 禁用裁剪\r\n if ((clonedGantt as any).scenegraph?.ganttGroup) {\r\n (clonedGantt as any).scenegraph.ganttGroup.setAttribute('clip', false);\r\n }\r\n if ((clonedGantt.taskListTableInstance as any)?.scenegraph?.tableGroup) {\r\n (clonedGantt.taskListTableInstance as any).scenegraph.tableGroup.setAttribute('clip', false);\r\n }\r\n\r\n clonedGantt.scenegraph.stage.render();\r\n\r\n return { tempContainer, clonedGantt };\r\n } catch (err) {\r\n // 清理创建的DOM元素\r\n if (tempContainer && tempContainer.parentNode) {\r\n tempContainer.remove();\r\n }\r\n console.error('无法导入甘特图组件,请确保已安装 @visactor/vtable-gantt 依赖', err);\r\n throw new Error('导出甘特图需要安装 @visactor/vtable-gantt 依赖');\r\n }\r\n }\r\n private finalizeExport(\r\n canvas: HTMLCanvasElement,\r\n fileName: string,\r\n type: string,\r\n quality: number,\r\n download: boolean = true\r\n ): string {\r\n const base64 = canvas.toDataURL(`image/${type}`, quality);\r\n\r\n // 如果需要下载,则创建下载链接\r\n if (download) {\r\n const link = document.createElement('a');\r\n link.download = `${fileName}.${type}`;\r\n link.href = base64;\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n }\r\n\r\n return base64;\r\n }\r\n\r\n release(): void {\r\n this._gantt = null;\r\n }\r\n}\r\n"]}
|
|
@@ -52,12 +52,12 @@ export class ConfigManager {
|
|
|
52
52
|
}));
|
|
53
53
|
}
|
|
54
54
|
processRecordsHierarchyStates(records) {
|
|
55
|
-
const HierarchyState = VTable.TYPES.HierarchyState,
|
|
55
|
+
const HierarchyState = VTable.TYPES.HierarchyState, hierarchyExpandLevel = this.table.options.hierarchyExpandLevel || this.table.options.headerExpandLevel;
|
|
56
56
|
(recordList => {
|
|
57
57
|
recordList.forEach((record => {
|
|
58
58
|
if (record && "object" == typeof record) {
|
|
59
59
|
const recordObj = record;
|
|
60
|
-
(this.hasChildren(record) || !0 === recordObj.children) && ("expand" === recordObj.hierarchyState ? recordObj.hierarchyState = HierarchyState.expand : "collapse" === recordObj.hierarchyState ? recordObj.hierarchyState = HierarchyState.collapse : recordObj.hierarchyState || (recordObj.hierarchyState =
|
|
60
|
+
(this.hasChildren(record) || !0 === recordObj.children) && ("expand" === recordObj.hierarchyState ? recordObj.hierarchyState = HierarchyState.expand : "collapse" === recordObj.hierarchyState ? recordObj.hierarchyState = HierarchyState.collapse : recordObj.hierarchyState || (recordObj.hierarchyState = hierarchyExpandLevel && hierarchyExpandLevel > 1 ? HierarchyState.expand : HierarchyState.collapse));
|
|
61
61
|
}
|
|
62
62
|
}));
|
|
63
63
|
})(records), this.performInitialExpansion();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/master-detail-plugin/config.ts"],"names":[],"mappings":"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","file":"config.js","sourcesContent":["import * as VTable from '@visactor/vtable';\r\nimport type { DetailTableOptions, MasterDetailPluginOptions } from './types';\r\n\r\n/**\r\n * 配置注入相关功能\r\n */\r\nexport class ConfigManager {\r\n private expandRowCallback?: (rowIndex: number) => void;\r\n\r\n constructor(private pluginOptions: MasterDetailPluginOptions, private table: VTable.ListTable) {}\r\n\r\n /**\r\n * 设置展开行的回调函数\r\n */\r\n setExpandRowCallback(callback: (rowIndex: number) => void): void {\r\n this.expandRowCallback = callback;\r\n }\r\n\r\n /**\r\n * 检查记录是否有子数据\r\n */\r\n private hasChildren(record: unknown): boolean {\r\n if (record && typeof record === 'object' && 'children' in record) {\r\n const children = record.children;\r\n return Array.isArray(children) && children.length > 0;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * 注入主从表配置到表格选项中\r\n */\r\n injectMasterDetailOptions(options: VTable.ListTableConstructorOptions): void {\r\n // 启用主从表基础设施\r\n (options as VTable.ListTableConstructorOptions & { masterDetail: boolean }).masterDetail = true;\r\n if (!options.customConfig) {\r\n options.customConfig = {};\r\n }\r\n // 确保滚动事件始终触发,用于子表位置同步\r\n options.customConfig.scrollEventAlwaysTrigger = true;\r\n const originalCustomComputeRowHeight = options.customComputeRowHeight;\r\n // 这个customComputeRowHeight用来保持展开行的高度\r\n options.customComputeRowHeight = params => {\r\n const { row, table } = params;\r\n if (this.isRowExpanded(row)) {\r\n const expandedHeight = table.getRowHeight(row);\r\n if (Array.isArray(expandedHeight)) {\r\n return expandedHeight[0] ?? 'auto';\r\n }\r\n return expandedHeight as number | 'auto';\r\n }\r\n if (originalCustomComputeRowHeight) {\r\n const userResult = originalCustomComputeRowHeight(params);\r\n if (userResult !== undefined && userResult !== null) {\r\n return userResult;\r\n }\r\n }\r\n };\r\n\r\n // 设置第一列为树形结构,是为什么方便getHierarchyState等的判断,他们需要有tree的配置,这不会导致主从表变为tree的状态,因为在_setRecords的时候会直接强制设置为grid\r\n if (options.columns && options.columns.length > 0) {\r\n const firstColumn = options.columns[0] as VTable.TYPES.ColumnDefine;\r\n firstColumn.tree = true;\r\n }\r\n\r\n // 监听表格初始化完成事件,设置图标\r\n this.setupInitializedListener();\r\n\r\n // 注入子表配置\r\n if (this.pluginOptions.detailTableOptions) {\r\n const detailOptions = this.pluginOptions.detailTableOptions;\r\n // 判断是静态配置还是动态函数\r\n if (typeof detailOptions === 'function') {\r\n // 动态配置:根据数据和行索引返回不同的子表配置\r\n (\r\n options as VTable.ListTableConstructorOptions & {\r\n getDetailGridOptions: (params: { data: unknown; bodyRowIndex: number }) => DetailTableOptions;\r\n }\r\n ).getDetailGridOptions = detailOptions;\r\n } else {\r\n // 静态配置:所有子表使用相同配置\r\n (\r\n options as VTable.ListTableConstructorOptions & { detailTableOptions: DetailTableOptions }\r\n ).detailTableOptions = detailOptions;\r\n }\r\n }\r\n // 禁用 _refreshHierarchyState 方法\r\n this.disableRefreshHierarchyState();\r\n }\r\n\r\n /**\r\n * 禁用VTable的_refreshHierarchyState方法\r\n */\r\n private disableRefreshHierarchyState(): void {\r\n // 延迟执行,确保表格已经创建完成\r\n setTimeout(() => {\r\n const tableWithPrivateMethod = this.table as unknown as {\r\n _refreshHierarchyState?: () => void;\r\n _originalRefreshHierarchyState?: () => void;\r\n };\r\n if (tableWithPrivateMethod && typeof tableWithPrivateMethod._refreshHierarchyState === 'function') {\r\n tableWithPrivateMethod._originalRefreshHierarchyState = tableWithPrivateMethod._refreshHierarchyState;\r\n tableWithPrivateMethod._refreshHierarchyState = () => {\r\n // 禁用_refreshHierarchyState函数\r\n };\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * 处理图标的显示\r\n */\r\n private setupInitializedListener(): void {\r\n // 监听表格初始化完成事件\r\n this.table.on('initialized', () => {\r\n const records = this.table.dataSource.records;\r\n this.processRecordsHierarchyStates(records);\r\n this.table.renderWithRecreateCells();\r\n });\r\n }\r\n\r\n /**\r\n * 处理记录的层级状态\r\n */\r\n private processRecordsHierarchyStates(records: unknown[]): void {\r\n const HierarchyState = VTable.TYPES.HierarchyState;\r\n const headerExpandLevel = this.table.options.headerExpandLevel;\r\n const processRecords = (recordList: unknown[]) => {\r\n recordList.forEach(record => {\r\n if (record && typeof record === 'object') {\r\n const recordObj = record as Record<string, unknown>;\r\n // 处理有子数据的记录\r\n if (this.hasChildren(record) || recordObj.children === true) {\r\n // 优先级:records 中的 hierarchyState > headerExpandLevel\r\n if (recordObj.hierarchyState === 'expand') {\r\n // 明确设置为展开\r\n recordObj.hierarchyState = HierarchyState.expand;\r\n } else if (recordObj.hierarchyState === 'collapse') {\r\n // 明确设置为收起\r\n recordObj.hierarchyState = HierarchyState.collapse;\r\n } else if (!recordObj.hierarchyState) {\r\n // 没有明确设置,根据 headerExpandLevel 决定\r\n if (headerExpandLevel && headerExpandLevel > 1) {\r\n recordObj.hierarchyState = HierarchyState.expand;\r\n } else {\r\n recordObj.hierarchyState = HierarchyState.collapse;\r\n }\r\n }\r\n }\r\n }\r\n });\r\n };\r\n processRecords(records);\r\n this.performInitialExpansion();\r\n }\r\n\r\n /**\r\n * 遍历所有记录,根据 hierarchyState 状态执行初始展开\r\n * 与VTable的异步CellGroup创建过程同步,在每个CellGroup创建后检查是否需要展开\r\n */\r\n private performInitialExpansion(): void {\r\n // 获取需要展开的记录索引列表\r\n const expandableRecords = this.getExpandableRecords();\r\n if (expandableRecords.length === 0) {\r\n return;\r\n }\r\n\r\n // 开始异步展开过程,与VTable的渲染频率同步\r\n this.startAsyncExpansion(expandableRecords);\r\n }\r\n\r\n /**\r\n * 获取所有需要展开的记录信息\r\n */\r\n private getExpandableRecords(): Array<{ recordIndex: number; actualRowIndex: number; record: unknown }> {\r\n const dataSource = this.table.dataSource as unknown as {\r\n source?: unknown[];\r\n _source?: unknown[];\r\n records: unknown[];\r\n };\r\n const allRecords = dataSource.source || dataSource._source || this.table.dataSource.records;\r\n const HierarchyState = VTable.TYPES.HierarchyState;\r\n const expandableRecords: Array<{ recordIndex: number; actualRowIndex: number; record: unknown }> = [];\r\n\r\n // 获取插件内部属性来访问 expandedRecordIndices\r\n const tableWithInternalProps = this.table as unknown as {\r\n internalProps: { expandedRecordIndices: number[] };\r\n };\r\n if (!tableWithInternalProps.internalProps.expandedRecordIndices) {\r\n tableWithInternalProps.internalProps.expandedRecordIndices = [];\r\n }\r\n const expandedRecordIndices = tableWithInternalProps.internalProps.expandedRecordIndices;\r\n\r\n // 遍历所有记录,收集需要展开的行\r\n for (let recordIndex = 0; recordIndex < allRecords.length; recordIndex++) {\r\n const record = allRecords[recordIndex];\r\n if (record && typeof record === 'object') {\r\n const recordObj = record as Record<string, unknown>;\r\n // 检查是否需要展开\r\n if (\r\n (this.hasChildren(record) || recordObj.children === true) &&\r\n recordObj.hierarchyState === HierarchyState.expand\r\n ) {\r\n // 将记录索引添加到 expandedRecordIndices 中\r\n if (!expandedRecordIndices.includes(recordIndex)) {\r\n expandedRecordIndices.push(recordIndex);\r\n }\r\n // 尝试获取行索引\r\n try {\r\n const bodyRowIndex = this.table.getBodyRowIndexByRecordIndex(recordIndex);\r\n if (bodyRowIndex >= 0) {\r\n const actualRowIndex = bodyRowIndex + this.table.columnHeaderLevelCount;\r\n expandableRecords.push({ recordIndex, actualRowIndex, record });\r\n }\r\n } catch (error) {\r\n // 记录可能不在当前页面中,跳过\r\n }\r\n }\r\n }\r\n }\r\n\r\n return expandableRecords;\r\n }\r\n\r\n /**\r\n * 开始异步展开过程,与VTable的异步渲染同步\r\n */\r\n private startAsyncExpansion(\r\n expandableRecords: Array<{ recordIndex: number; actualRowIndex: number; record: unknown }>\r\n ): void {\r\n let currentIndex = 0;\r\n\r\n const processNextExpansion = (): void => {\r\n if (currentIndex >= expandableRecords.length) {\r\n return; // 所有展开操作完成\r\n }\r\n\r\n const { actualRowIndex } = expandableRecords[currentIndex];\r\n // 检查该行的CellGroup是否已经创建\r\n if (this.isCellGroupCreated(actualRowIndex)) {\r\n // CellGroup已创建,立即执行展开\r\n if (this.expandRowCallback) {\r\n this.expandRowCallback(actualRowIndex);\r\n }\r\n currentIndex++;\r\n // 立即处理下一个,避免不必要的延迟\r\n setTimeout(processNextExpansion, 0);\r\n } else {\r\n // CellGroup尚未创建,等待16ms后再检查(与VTable的异步渲染频率同步)\r\n setTimeout(processNextExpansion, 16);\r\n }\r\n };\r\n // 启动异步展开过程\r\n setTimeout(processNextExpansion, 0);\r\n }\r\n\r\n /**\r\n * 检查指定行的CellGroup是否已经创建\r\n */\r\n private isCellGroupCreated(rowIndex: number): boolean {\r\n try {\r\n // 检查第一列的CellGroup是否存在且有效\r\n const cellGroup = this.table.scenegraph.getCell(0, rowIndex);\r\n return cellGroup && cellGroup.role === 'cell';\r\n } catch (error) {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * 获取详情配置\r\n */\r\n getDetailConfigForRecord(record: unknown, bodyRowIndex: number): DetailTableOptions | null {\r\n const detailOptions = this.pluginOptions.detailTableOptions;\r\n if (!detailOptions) {\r\n return null;\r\n }\r\n // 判断是函数还是静态配置\r\n if (typeof detailOptions === 'function') {\r\n return detailOptions({ data: record, bodyRowIndex: bodyRowIndex });\r\n }\r\n return detailOptions;\r\n }\r\n\r\n private isRowExpanded: (row: number) => boolean = () => false;\r\n\r\n /**\r\n * 设置行展开状态检查函数\r\n */\r\n setRowExpandedChecker(checker: (row: number) => boolean): void {\r\n this.isRowExpanded = checker;\r\n }\r\n\r\n /**\r\n * 释放所有资源和引用\r\n */\r\n release(): void {\r\n this.isRowExpanded = () => false;\r\n // 清理对表格的引用\r\n (this as unknown as { table: VTable.ListTable | null }).table = null;\r\n (this as unknown as { pluginOptions: MasterDetailPluginOptions | null }).pluginOptions = null;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/master-detail-plugin/config.ts"],"names":[],"mappings":"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","file":"config.js","sourcesContent":["import * as VTable from '@visactor/vtable';\r\nimport type { DetailTableOptions, MasterDetailPluginOptions } from './types';\r\n\r\n/**\r\n * 配置注入相关功能\r\n */\r\nexport class ConfigManager {\r\n private expandRowCallback?: (rowIndex: number) => void;\r\n\r\n constructor(private pluginOptions: MasterDetailPluginOptions, private table: VTable.ListTable) {}\r\n\r\n /**\r\n * 设置展开行的回调函数\r\n */\r\n setExpandRowCallback(callback: (rowIndex: number) => void): void {\r\n this.expandRowCallback = callback;\r\n }\r\n\r\n /**\r\n * 检查记录是否有子数据\r\n */\r\n private hasChildren(record: unknown): boolean {\r\n if (record && typeof record === 'object' && 'children' in record) {\r\n const children = record.children;\r\n return Array.isArray(children) && children.length > 0;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * 注入主从表配置到表格选项中\r\n */\r\n injectMasterDetailOptions(options: VTable.ListTableConstructorOptions): void {\r\n // 启用主从表基础设施\r\n (options as VTable.ListTableConstructorOptions & { masterDetail: boolean }).masterDetail = true;\r\n if (!options.customConfig) {\r\n options.customConfig = {};\r\n }\r\n // 确保滚动事件始终触发,用于子表位置同步\r\n options.customConfig.scrollEventAlwaysTrigger = true;\r\n const originalCustomComputeRowHeight = options.customComputeRowHeight;\r\n // 这个customComputeRowHeight用来保持展开行的高度\r\n options.customComputeRowHeight = params => {\r\n const { row, table } = params;\r\n if (this.isRowExpanded(row)) {\r\n const expandedHeight = table.getRowHeight(row);\r\n if (Array.isArray(expandedHeight)) {\r\n return expandedHeight[0] ?? 'auto';\r\n }\r\n return expandedHeight as number | 'auto';\r\n }\r\n if (originalCustomComputeRowHeight) {\r\n const userResult = originalCustomComputeRowHeight(params);\r\n if (userResult !== undefined && userResult !== null) {\r\n return userResult;\r\n }\r\n }\r\n };\r\n\r\n // 设置第一列为树形结构,是为什么方便getHierarchyState等的判断,他们需要有tree的配置,这不会导致主从表变为tree的状态,因为在_setRecords的时候会直接强制设置为grid\r\n if (options.columns && options.columns.length > 0) {\r\n const firstColumn = options.columns[0] as VTable.TYPES.ColumnDefine;\r\n firstColumn.tree = true;\r\n }\r\n\r\n // 监听表格初始化完成事件,设置图标\r\n this.setupInitializedListener();\r\n\r\n // 注入子表配置\r\n if (this.pluginOptions.detailTableOptions) {\r\n const detailOptions = this.pluginOptions.detailTableOptions;\r\n // 判断是静态配置还是动态函数\r\n if (typeof detailOptions === 'function') {\r\n // 动态配置:根据数据和行索引返回不同的子表配置\r\n (\r\n options as VTable.ListTableConstructorOptions & {\r\n getDetailGridOptions: (params: { data: unknown; bodyRowIndex: number }) => DetailTableOptions;\r\n }\r\n ).getDetailGridOptions = detailOptions;\r\n } else {\r\n // 静态配置:所有子表使用相同配置\r\n (\r\n options as VTable.ListTableConstructorOptions & { detailTableOptions: DetailTableOptions }\r\n ).detailTableOptions = detailOptions;\r\n }\r\n }\r\n // 禁用 _refreshHierarchyState 方法\r\n this.disableRefreshHierarchyState();\r\n }\r\n\r\n /**\r\n * 禁用VTable的_refreshHierarchyState方法\r\n */\r\n private disableRefreshHierarchyState(): void {\r\n // 延迟执行,确保表格已经创建完成\r\n setTimeout(() => {\r\n const tableWithPrivateMethod = this.table as unknown as {\r\n _refreshHierarchyState?: () => void;\r\n _originalRefreshHierarchyState?: () => void;\r\n };\r\n if (tableWithPrivateMethod && typeof tableWithPrivateMethod._refreshHierarchyState === 'function') {\r\n tableWithPrivateMethod._originalRefreshHierarchyState = tableWithPrivateMethod._refreshHierarchyState;\r\n tableWithPrivateMethod._refreshHierarchyState = () => {\r\n // 禁用_refreshHierarchyState函数\r\n };\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * 处理图标的显示\r\n */\r\n private setupInitializedListener(): void {\r\n // 监听表格初始化完成事件\r\n this.table.on('initialized', () => {\r\n const records = this.table.dataSource.records;\r\n this.processRecordsHierarchyStates(records);\r\n this.table.renderWithRecreateCells();\r\n });\r\n }\r\n\r\n /**\r\n * 处理记录的层级状态\r\n */\r\n private processRecordsHierarchyStates(records: unknown[]): void {\r\n const HierarchyState = VTable.TYPES.HierarchyState;\r\n // 兼容处理headerExpandLevel\r\n const hierarchyExpandLevel = this.table.options.hierarchyExpandLevel || this.table.options.headerExpandLevel;\r\n const processRecords = (recordList: unknown[]) => {\r\n recordList.forEach(record => {\r\n if (record && typeof record === 'object') {\r\n const recordObj = record as Record<string, unknown>;\r\n // 处理有子数据的记录\r\n if (this.hasChildren(record) || recordObj.children === true) {\r\n // 优先级:records 中的 hierarchyState > hierarchyExpandLevel\r\n if (recordObj.hierarchyState === 'expand') {\r\n // 明确设置为展开\r\n recordObj.hierarchyState = HierarchyState.expand;\r\n } else if (recordObj.hierarchyState === 'collapse') {\r\n // 明确设置为收起\r\n recordObj.hierarchyState = HierarchyState.collapse;\r\n } else if (!recordObj.hierarchyState) {\r\n // 没有明确设置,根据 hierarchyExpandLevel 决定\r\n if (hierarchyExpandLevel && hierarchyExpandLevel > 1) {\r\n recordObj.hierarchyState = HierarchyState.expand;\r\n } else {\r\n recordObj.hierarchyState = HierarchyState.collapse;\r\n }\r\n }\r\n }\r\n }\r\n });\r\n };\r\n processRecords(records);\r\n this.performInitialExpansion();\r\n }\r\n\r\n /**\r\n * 遍历所有记录,根据 hierarchyState 状态执行初始展开\r\n * 与VTable的异步CellGroup创建过程同步,在每个CellGroup创建后检查是否需要展开\r\n */\r\n private performInitialExpansion(): void {\r\n // 获取需要展开的记录索引列表\r\n const expandableRecords = this.getExpandableRecords();\r\n if (expandableRecords.length === 0) {\r\n return;\r\n }\r\n\r\n // 开始异步展开过程,与VTable的渲染频率同步\r\n this.startAsyncExpansion(expandableRecords);\r\n }\r\n\r\n /**\r\n * 获取所有需要展开的记录信息\r\n */\r\n private getExpandableRecords(): Array<{ recordIndex: number; actualRowIndex: number; record: unknown }> {\r\n const dataSource = this.table.dataSource as unknown as {\r\n source?: unknown[];\r\n _source?: unknown[];\r\n records: unknown[];\r\n };\r\n const allRecords = dataSource.source || dataSource._source || this.table.dataSource.records;\r\n const HierarchyState = VTable.TYPES.HierarchyState;\r\n const expandableRecords: Array<{ recordIndex: number; actualRowIndex: number; record: unknown }> = [];\r\n\r\n // 获取插件内部属性来访问 expandedRecordIndices\r\n const tableWithInternalProps = this.table as unknown as {\r\n internalProps: { expandedRecordIndices: number[] };\r\n };\r\n if (!tableWithInternalProps.internalProps.expandedRecordIndices) {\r\n tableWithInternalProps.internalProps.expandedRecordIndices = [];\r\n }\r\n const expandedRecordIndices = tableWithInternalProps.internalProps.expandedRecordIndices;\r\n\r\n // 遍历所有记录,收集需要展开的行\r\n for (let recordIndex = 0; recordIndex < allRecords.length; recordIndex++) {\r\n const record = allRecords[recordIndex];\r\n if (record && typeof record === 'object') {\r\n const recordObj = record as Record<string, unknown>;\r\n // 检查是否需要展开\r\n if (\r\n (this.hasChildren(record) || recordObj.children === true) &&\r\n recordObj.hierarchyState === HierarchyState.expand\r\n ) {\r\n // 将记录索引添加到 expandedRecordIndices 中\r\n if (!expandedRecordIndices.includes(recordIndex)) {\r\n expandedRecordIndices.push(recordIndex);\r\n }\r\n // 尝试获取行索引\r\n try {\r\n const bodyRowIndex = this.table.getBodyRowIndexByRecordIndex(recordIndex);\r\n if (bodyRowIndex >= 0) {\r\n const actualRowIndex = bodyRowIndex + this.table.columnHeaderLevelCount;\r\n expandableRecords.push({ recordIndex, actualRowIndex, record });\r\n }\r\n } catch (error) {\r\n // 记录可能不在当前页面中,跳过\r\n }\r\n }\r\n }\r\n }\r\n\r\n return expandableRecords;\r\n }\r\n\r\n /**\r\n * 开始异步展开过程,与VTable的异步渲染同步\r\n */\r\n private startAsyncExpansion(\r\n expandableRecords: Array<{ recordIndex: number; actualRowIndex: number; record: unknown }>\r\n ): void {\r\n let currentIndex = 0;\r\n\r\n const processNextExpansion = (): void => {\r\n if (currentIndex >= expandableRecords.length) {\r\n return; // 所有展开操作完成\r\n }\r\n\r\n const { actualRowIndex } = expandableRecords[currentIndex];\r\n // 检查该行的CellGroup是否已经创建\r\n if (this.isCellGroupCreated(actualRowIndex)) {\r\n // CellGroup已创建,立即执行展开\r\n if (this.expandRowCallback) {\r\n this.expandRowCallback(actualRowIndex);\r\n }\r\n currentIndex++;\r\n // 立即处理下一个,避免不必要的延迟\r\n setTimeout(processNextExpansion, 0);\r\n } else {\r\n // CellGroup尚未创建,等待16ms后再检查(与VTable的异步渲染频率同步)\r\n setTimeout(processNextExpansion, 16);\r\n }\r\n };\r\n // 启动异步展开过程\r\n setTimeout(processNextExpansion, 0);\r\n }\r\n\r\n /**\r\n * 检查指定行的CellGroup是否已经创建\r\n */\r\n private isCellGroupCreated(rowIndex: number): boolean {\r\n try {\r\n // 检查第一列的CellGroup是否存在且有效\r\n const cellGroup = this.table.scenegraph.getCell(0, rowIndex);\r\n return cellGroup && cellGroup.role === 'cell';\r\n } catch (error) {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * 获取详情配置\r\n */\r\n getDetailConfigForRecord(record: unknown, bodyRowIndex: number): DetailTableOptions | null {\r\n const detailOptions = this.pluginOptions.detailTableOptions;\r\n if (!detailOptions) {\r\n return null;\r\n }\r\n // 判断是函数还是静态配置\r\n if (typeof detailOptions === 'function') {\r\n return detailOptions({ data: record, bodyRowIndex: bodyRowIndex });\r\n }\r\n return detailOptions;\r\n }\r\n\r\n private isRowExpanded: (row: number) => boolean = () => false;\r\n\r\n /**\r\n * 设置行展开状态检查函数\r\n */\r\n setRowExpandedChecker(checker: (row: number) => boolean): void {\r\n this.isRowExpanded = checker;\r\n }\r\n\r\n /**\r\n * 释放所有资源和引用\r\n */\r\n release(): void {\r\n this.isRowExpanded = () => false;\r\n // 清理对表格的引用\r\n (this as unknown as { table: VTable.ListTable | null }).table = null;\r\n (this as unknown as { pluginOptions: MasterDetailPluginOptions | null }).pluginOptions = null;\r\n }\r\n}\r\n"]}
|
|
@@ -12,7 +12,7 @@ export function exportVTableToCsv(tableInstance, option) {
|
|
|
12
12
|
const strCellValue = `${void 0 === copyCellValue ? "" : copyCellValue}`;
|
|
13
13
|
/^\[object .*\]$/.exec(strCellValue) || (copyValue += strCellValue);
|
|
14
14
|
}
|
|
15
|
-
copyValue += ",";
|
|
15
|
+
col !== maxCol && (copyValue += ",");
|
|
16
16
|
}
|
|
17
17
|
copyValue += "\r\n";
|
|
18
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/table-export/csv/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAK5D,MAAM,OAAO,GAAG,MAAM,CAAC;AACvB,MAAM,SAAS,GAAG,GAAG,CAAC;AAUtB,MAAM,UAAU,iBAAiB,CAC/B,aAAkD,EAClD,MAAiC;IAEjC,MAAM,aAAa,GAAG,CAAC,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,aAAa,CAAA,CAAC;IAC9C,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,sBAAsB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IACvF,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,GAAG,CAAC,CAAC;IAE1C,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,KAAK,IAAI,GAAG,GAAG,MAAM,EAAE,GAAG,IAAI,MAAM,EAAE,GAAG,EAAE,EAAE;QAC3C,KAAK,IAAI,GAAG,GAAG,MAAM,EAAE,GAAG,IAAI,MAAM,EAAE,GAAG,EAAE,EAAE;YAC3C,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;YACxE,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,aAAa,YAAY,OAAO,EAAE;aAEvE;iBAAM;gBACL,MAAM,YAAY,GAAG,GAAG,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;gBAC3E,IAAI,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;iBAEzC;qBAAM;oBACL,SAAS,IAAI,YAAY,CAAC;iBAC3B;aACF;YACD,SAAS,IAAI,SAAS,CAAC;
|
|
1
|
+
{"version":3,"sources":["../src/table-export/csv/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ListTable, PivotTable, PivotChart, TYPES } from '@visactor/vtable';\nimport type { CellInfo } from '../excel';\nimport { handlePaginationExport } from '../util/pagination';\n\ntype IVTable = ListTable | PivotTable | PivotChart;\ntype CellRange = TYPES.CellRange;\n\nconst newLine = '\\r\\n';\nconst separator = ',';\n\nexport type ExportVTableToCsvOptions = {\n formatExportOutput?: (cellInfo: CellInfo) => string | undefined;\n escape?: boolean;\n exportAllData?: boolean;\n downloadFile?: boolean;\n fileName?: string;\n};\n\nexport function exportVTableToCsv(\n tableInstance: ListTable | PivotTable | PivotChart,\n option?: ExportVTableToCsvOptions\n): string {\n const exportAllData = !!option?.exportAllData;\n const { handleRowCount, reset } = handlePaginationExport(tableInstance, exportAllData);\n const minRow = 0;\n const maxRow = handleRowCount();\n const minCol = 0;\n const maxCol = tableInstance.colCount - 1;\n\n let copyValue = '';\n for (let row = minRow; row <= maxRow; row++) {\n for (let col = minCol; col <= maxCol; col++) {\n const copyCellValue = getCopyCellValue(col, row, tableInstance, option);\n if (typeof Promise !== 'undefined' && copyCellValue instanceof Promise) {\n // not support async\n } else {\n const strCellValue = `${copyCellValue === undefined ? '' : copyCellValue}`;\n if (/^\\[object .*\\]$/.exec(strCellValue)) {\n // ignore object\n } else {\n copyValue += strCellValue;\n }\n }\n if (col !== maxCol) {\n copyValue += separator;\n }\n }\n copyValue += newLine;\n }\n // 恢复透视表的pagination配置\n reset();\n return copyValue;\n}\n\nfunction getCopyCellValue(\n col: number,\n row: number,\n tableInstance: ListTable | PivotTable | PivotChart,\n option?: ExportVTableToCsvOptions\n): string | Promise<string> | void {\n const rawRecord = tableInstance.getCellRawRecord(col, row);\n const cellValue = (rawRecord && rawRecord.vtableMergeName) ?? tableInstance.getCellValue(col, row, false);\n\n if (option?.formatExportOutput) {\n const cellType = tableInstance.getCellType(col, row);\n const cellInfo = { cellType, cellValue, table: tableInstance, col, row };\n const formattedValue = option.formatExportOutput(cellInfo);\n if (formattedValue !== undefined) {\n if (typeof formattedValue === 'string') {\n return '\"' + formattedValue + '\"';\n }\n return formattedValue;\n }\n }\n const cellRange: CellRange = tableInstance.getCellRange(col, row);\n const copyStartCol = cellRange.start.col;\n const copyStartRow = cellRange.start.row;\n\n if (copyStartCol !== col || copyStartRow !== row) {\n return '';\n }\n\n let value = cellValue;\n if (option?.escape) {\n value = escapeForCSV(value);\n } else if (typeof value === 'string') {\n value = '\"' + value + '\"';\n }\n return value;\n}\n\n/**\n * 将字符串中的特殊符号进行转义,以避免干扰CSV解析\n * @param {string} str - 需要处理的字符串\n * @return {string} - 已处理的字符串\n */\nfunction escapeForCSV(str: any) {\n if (typeof str !== 'string') {\n return str;\n }\n\n // 替换双引号为两个双引号\n let escapedStr = str.replace(/\"/g, '\"\"');\n\n // 如果字符串中包含逗号、换行符或双引号,则需要用双引号包裹\n if (/[,\"\\r\\n]/.test(escapedStr)) {\n escapedStr = `\"${escapedStr}\"`;\n }\n\n return escapedStr;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visactor/vtable-plugins",
|
|
3
|
-
"version": "1.22.4
|
|
3
|
+
"version": "1.22.4",
|
|
4
4
|
"description": "The search util of VTable",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "VisActor",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"@types/file-saver": "2.0.7"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"@visactor/vtable": "1.22.4
|
|
46
|
-
"@visactor/vtable-gantt": "1.22.4
|
|
45
|
+
"@visactor/vtable": "1.22.4",
|
|
46
|
+
"@visactor/vtable-gantt": "1.22.4"
|
|
47
47
|
},
|
|
48
48
|
"peerDependenciesMeta": {
|
|
49
49
|
"@visactor/vtable-gantt": {
|
|
@@ -53,9 +53,6 @@
|
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"cross-env": "^7.0.3",
|
|
55
55
|
"increase-memory-limit": "^1.0.7",
|
|
56
|
-
"@visactor/vtable": "1.22.4-alpha.2",
|
|
57
|
-
"@visactor/vtable-editors": "1.22.4-alpha.2",
|
|
58
|
-
"@visactor/vtable-gantt": "1.22.4-alpha.2",
|
|
59
56
|
"@visactor/vchart": "2.0.2",
|
|
60
57
|
"@rushstack/eslint-patch": "~1.1.4",
|
|
61
58
|
"react": "^18.0.0",
|
|
@@ -98,9 +95,12 @@
|
|
|
98
95
|
"@types/react-is": "^17.0.3",
|
|
99
96
|
"rollup-plugin-node-resolve": "5.2.0",
|
|
100
97
|
"@types/lodash": "4.14.182",
|
|
101
|
-
"@
|
|
98
|
+
"@visactor/vtable": "1.22.4",
|
|
99
|
+
"@visactor/vtable-gantt": "1.22.4",
|
|
102
100
|
"@internal/bundler": "0.0.1",
|
|
103
|
-
"@internal/eslint-config": "0.0.1"
|
|
101
|
+
"@internal/eslint-config": "0.0.1",
|
|
102
|
+
"@visactor/vtable-editors": "1.22.4",
|
|
103
|
+
"@internal/ts-config": "0.0.1"
|
|
104
104
|
},
|
|
105
105
|
"scripts": {
|
|
106
106
|
"demo": "vite ./demo",
|