arthub-table 0.2.0-beta.2 → 0.2.0-beta.21

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.
@@ -194,3 +194,17 @@ export declare function preprocessSingleRow(rawRow: Record<string, any>, allHead
194
194
  controllerProps: Record<string, any>;
195
195
  tableIndex?: number;
196
196
  }): PreprocessedRow;
197
+ /**
198
+ * Rebuild _nestedData for specific nested columns on given preprocessed rows.
199
+ *
200
+ * This extracts the nested data construction logic from convertToDataGridRows,
201
+ * allowing incremental rebuild of _nestedData when a child column's data changes
202
+ * (e.g. file/image upload in a nested sub-table) without a full data refresh.
203
+ *
204
+ * @param rows - Preprocessed row array (same as body.data / _dataGridData)
205
+ * @param rawRows - Raw row data array (same as tableDataList)
206
+ * @param nestedParentKeys - Keys of the nested parent columns to rebuild
207
+ * @param allHeaders - All column headers (including nested columns with children)
208
+ * @param props - Controller props (pipelineViewKey, displayTaskNum, iconUrlPrefix, etc.)
209
+ */
210
+ export declare function rebuildNestedColumnData(rows: PreprocessedRow[], rawRows: Record<string, any>[], nestedParentKeys: string[], allHeaders: ITableHeader[], props: Record<string, any>): void;
@@ -50,6 +50,7 @@ interface AutofillState {
50
50
  }
51
51
  interface RowDragState {
52
52
  isDragging: boolean;
53
+ dragStartX: number;
53
54
  dragStartY: number;
54
55
  draggedRowIndices: number[];
55
56
  dropIndicatorType: 'line' | 'overlay' | null;
@@ -500,7 +501,13 @@ export interface DataGridOptions {
500
501
  height: number;
501
502
  };
502
503
  }) => void;
503
- /** 折叠所有任务回调 */
504
+ /** 嵌套表格展开/收起回调:展开全部或收起按钮点击时触发,用于通知业务层更新数据 */
505
+ onNestedExpandToggle?: (info: {
506
+ parentRowData: any;
507
+ parentColKey: string;
508
+ parentRowIndex: number;
509
+ expanded: boolean;
510
+ }) => void;
504
511
  onCollapseAll?: () => void;
505
512
  /** 展开所有任务回调 */
506
513
  onExpandAll?: () => void;
@@ -951,6 +958,8 @@ declare class DataGrid {
951
958
  private static readonly MAX_CONSECUTIVE_RENDER_ERRORS;
952
959
  perfMonitor: PerformanceMonitor;
953
960
  wfStateStyle: 'icon' | 'tag';
961
+ /** Minimum time (ms) a loading indicator must be visible before it can be hidden */
962
+ private static readonly MIN_LOADING_DISPLAY_MS;
954
963
  private loadingCells;
955
964
  private loadingRotation;
956
965
  private loadingImage;
@@ -1662,6 +1671,10 @@ declare class DataGrid {
1662
1671
  * 内部辅助:移除单个 loading 状态
1663
1672
  */
1664
1673
  private removeSingleLoading;
1674
+ /**
1675
+ * Check if there are any active loading cells.
1676
+ */
1677
+ hasLoadingCells(): boolean;
1665
1678
  /**
1666
1679
  * 查询指定 cellKey 是否处于 loading 状态
1667
1680
  */
@@ -17,7 +17,6 @@ interface EventTasks {
17
17
  declare class Events {
18
18
  grid: DataGrid;
19
19
  el: HTMLCanvasElement;
20
- isFirefox: boolean;
21
20
  eventTasks: EventTasks;
22
21
  constructor(grid: DataGrid, el: HTMLCanvasElement);
23
22
  init(): void;
@@ -139,7 +139,7 @@ declare class NestedGrid {
139
139
  col: number;
140
140
  row: number;
141
141
  }): boolean;
142
- isCellEditable(colIndex: number): boolean;
142
+ isCellEditable(colIndex: number, rowIndex?: number): boolean;
143
143
  getSelectLabel(colIndex: number, value: any): string;
144
144
  /**
145
145
  * 处理右键菜单事件,返回上下文信息
@@ -340,6 +340,11 @@ declare class NestedGrid {
340
340
  * 处理不同类型数据的包装和转换
341
341
  */
342
342
  private buildNestedViewerData;
343
+ /**
344
+ * Draw loading indicator for a nested cell.
345
+ * Mirrors Cell.drawLoadingIndicator logic: rotating icon at cell right side.
346
+ */
347
+ private drawNestedLoadingIndicator;
343
348
  /**
344
349
  * 兜底文本渲染(当 viewer 不可用时)
345
350
  */
@@ -0,0 +1,76 @@
1
+ /**
2
+ * RelatedTaskViewer - Related task cell renderer (Canvas implementation)
3
+ * Displays the first related task's configured display fields.
4
+ *
5
+ * Layout modes:
6
+ * - Single-line (default): task name | thumbnails | "label: value" pairs — all horizontal, vertically centered
7
+ * - Multi-line (when row is expanded by nested columns): one field per line, vertically stacked
8
+ */
9
+ import type { CellViewer, ViewerRenderContext, RelatedTaskViewerData } from './types';
10
+ declare class RelatedTaskViewer implements CellViewer<RelatedTaskViewerData> {
11
+ readonly type = "related-task";
12
+ private imageManager;
13
+ /** Track failed image URLs to avoid retrying */
14
+ private failedImages;
15
+ private _sm;
16
+ private get TEXT_COLOR();
17
+ private get LABEL_COLOR();
18
+ private get EMPTY_TEXT_COLOR();
19
+ private get DASHED_BORDER_COLOR();
20
+ constructor();
21
+ /**
22
+ * Calculate thumbnail height for single-line mode.
23
+ * Max height = cell height - top/bottom padding (4px each).
24
+ */
25
+ private getSingleLineThumbnailHeight;
26
+ /**
27
+ * Calculate thumbnail width for a given image, maintaining aspect ratio.
28
+ * If no image is cached yet, returns thumbHeight (square placeholder).
29
+ */
30
+ private getThumbnailWidth;
31
+ /**
32
+ * Draw an image within the given area according to the specified fit mode.
33
+ * Mirrors the logic in FileViewer.drawPreviewImage and ImageViewer.drawImageWithFit.
34
+ */
35
+ private drawImageWithFit;
36
+ /**
37
+ * Draw the related task cell content
38
+ */
39
+ draw(context: ViewerRenderContext, data: RelatedTaskViewerData): void;
40
+ private drawSingleLine;
41
+ /**
42
+ * Draw a single inline thumbnail at the given position (for single-line mode).
43
+ * @returns The X position after the thumbnail(s)
44
+ */
45
+ private drawInlineThumbnail;
46
+ private drawMultiLine;
47
+ /**
48
+ * Draw empty placeholder — consistent with other viewers
49
+ */
50
+ private drawEmptyPlaceholder;
51
+ /**
52
+ * Draw a file status/format icon when coverUrl is not available.
53
+ * Uses the same getIconByFileStatus logic as FileViewer for visual consistency.
54
+ */
55
+ private drawFileStatusIcon;
56
+ /**
57
+ * Draw a dashed rectangle placeholder for unloaded/missing images
58
+ */
59
+ private drawDashedPlaceholder;
60
+ /**
61
+ * Truncate text to fit within maxWidth, appending ellipsis if needed
62
+ */
63
+ private truncateText;
64
+ /**
65
+ * Handle click events on the cell.
66
+ * Detects clicks on file thumbnails and triggers onFileGoToDetail callback.
67
+ */
68
+ onClick(context: ViewerRenderContext, data: RelatedTaskViewerData, localX: number, localY: number): boolean;
69
+ /**
70
+ * Get cursor style for hover — show pointer on file thumbnails
71
+ */
72
+ getHitArea(context: ViewerRenderContext, data: RelatedTaskViewerData, localX: number, localY: number): string | null;
73
+ private calculateSingleLineThumbnailAreas;
74
+ private calculateMultiLineThumbnailAreas;
75
+ }
76
+ export default RelatedTaskViewer;
@@ -4,7 +4,6 @@
4
4
  */
5
5
  import type { CellViewer, ViewerRenderContext, StatusViewerData } from './types';
6
6
  /**
7
- * StatusViewer renders status values in cells
8
7
  * Supports icons, colored tags, and various status types
9
8
  */
10
9
  declare class StatusViewer implements CellViewer<StatusViewerData> {
@@ -40,6 +40,7 @@ export { default as ModuleColExpandViewer } from './ModuleColExpandViewer';
40
40
  export { default as ChildrenViewer } from './ChildrenViewer';
41
41
  export { default as OnlyShowErrorViewer } from './OnlyShowErrorViewer';
42
42
  export { default as PerspectiveViewer } from './PerspectiveViewer';
43
+ export { default as RelatedTaskViewer } from './RelatedTaskViewer';
43
44
  import TextViewer from './TextViewer';
44
45
  import DropdownViewer from './DropdownViewer';
45
46
  import ImageViewer from './ImageViewer';
@@ -76,6 +77,7 @@ import ModuleColExpandViewer from './ModuleColExpandViewer';
76
77
  import ChildrenViewer from './ChildrenViewer';
77
78
  import OnlyShowErrorViewer from './OnlyShowErrorViewer';
78
79
  import PerspectiveViewer from './PerspectiveViewer';
80
+ import RelatedTaskViewer from './RelatedTaskViewer';
79
81
  /**
80
82
  * Register all default viewers
81
83
  * Call this function once during application initialization
@@ -126,4 +128,5 @@ export declare const defaultViewers: {
126
128
  children: typeof ChildrenViewer;
127
129
  'only-show-error': typeof OnlyShowErrorViewer;
128
130
  perspective: typeof PerspectiveViewer;
131
+ 'related-task': typeof RelatedTaskViewer;
129
132
  };
@@ -625,6 +625,8 @@ export interface TextViewerWithSwitcherData extends CellViewerData {
625
625
  iconTooltip?: string;
626
626
  /** 商业化单子数(仅商业化库 name 列,由 businessData[rowId] 注入) */
627
627
  businessOrderCount?: number;
628
+ /** 点击任务图标回调(如跳转 TAPD 页面),与 DOM 版 onClickNameIcon + iconJumpUrl 对齐 */
629
+ onClickIcon?: (rowData: Record<string, any>) => void;
628
630
  }
629
631
  /**
630
632
  * 文件项信息
@@ -657,6 +659,8 @@ export interface FileViewerData extends CellViewerData {
657
659
  key?: string;
658
660
  /** 是否可编辑 */
659
661
  canEdit?: boolean;
662
+ /** 隐藏右侧操作区域(编辑笔/查看图标),用于嵌套表格中由 NestedGrid 层统一绘制编辑笔 */
663
+ hideAfterArea?: boolean;
660
664
  /** 是否显示删除线 */
661
665
  showLineThrow?: boolean;
662
666
  /** 是否关联属性 */
@@ -1260,3 +1264,56 @@ export interface RichTextViewerData extends CellViewerData {
1260
1264
  /** 占位符文本,默认 '-' */
1261
1265
  placeholder?: string;
1262
1266
  }
1267
+ /**
1268
+ * Related-task display field item
1269
+ */
1270
+ export interface RelatedTaskDisplayField {
1271
+ /** Field key (e.g. 'estimate_start_date') */
1272
+ key: string;
1273
+ /** Field display label (e.g. '预计开始时间') */
1274
+ label: string;
1275
+ /** Raw field value */
1276
+ value: any;
1277
+ /** Formatted display value (e.g. '2026/03/02') */
1278
+ displayValue: string;
1279
+ /** Whether this field is a file-type field */
1280
+ isFileType: boolean;
1281
+ /** File data for file-type fields (cover images, etc.) */
1282
+ fileData?: Array<{
1283
+ coverUrl: string;
1284
+ assetId?: number;
1285
+ status?: number;
1286
+ fileFormat?: string;
1287
+ }>;
1288
+ /** File meta key for file-type fields (e.g. 'deliverable') */
1289
+ fileMeta?: string;
1290
+ /** Node ID that owns this file (for opening asset detail) */
1291
+ nodeId?: number;
1292
+ }
1293
+ /**
1294
+ * Related-task Viewer data interface
1295
+ * Displays the first related task's configured display fields
1296
+ */
1297
+ export interface RelatedTaskViewerData extends CellViewerData {
1298
+ /** Structured value containing related task info */
1299
+ value: {
1300
+ /** First related task node ID */
1301
+ firstRelatedTaskId: number;
1302
+ /** First related task name */
1303
+ firstRelatedTaskName: string;
1304
+ /** Display label for the task name field (e.g. "名称") */
1305
+ firstRelatedTaskLabel?: string;
1306
+ /** All related node IDs (for future interactions) */
1307
+ allRelatedNodeIds: number[];
1308
+ /** Display fields with resolved values */
1309
+ displayFields: RelatedTaskDisplayField[];
1310
+ } | null;
1311
+ /** Thumbnail fit mode for file-type fields (synced from imageDisplayMode config) */
1312
+ thumbnailFit?: 'contain' | 'cover' | 'fill' | 'height-full' | 'width-full';
1313
+ /** Callback when user clicks a file thumbnail — opens asset detail page */
1314
+ onFileGoToDetail?: (file: {
1315
+ assetId: number;
1316
+ id: number;
1317
+ ids: number[];
1318
+ }, data: any) => void;
1319
+ }
@@ -41,7 +41,7 @@ export { CSS_PREFIX, HEADER_HEIGHT, ROW_INDEX_WIDTH, CHECK_BOX_WIDTH, CELL_HEIGH
41
41
  export { getFieldStatisticTypes } from './core/footer/utils';
42
42
  export { convertToDataGridColumns, } from './adapters/columnAdapter';
43
43
  export type { ITableHeader, } from './adapters/columnAdapter';
44
- export { convertToDataGridRows, isPerfLogEnabled, } from './adapters/rowDataAdapter';
44
+ export { convertToDataGridRows, isPerfLogEnabled, rebuildNestedColumnData, } from './adapters/rowDataAdapter';
45
45
  export type { PreprocessedRow, } from './adapters/rowDataAdapter';
46
46
  export { preprocessRowStyles, } from './adapters/styleAdapter';
47
47
  export type { RowStyleResult, } from './adapters/styleAdapter';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arthub-table",
3
- "version": "0.2.0-beta.2",
3
+ "version": "0.2.0-beta.21",
4
4
  "description": "High-performance canvas-based table/grid component for Vue 3 with TypeScript support, featuring virtual scrolling, cell viewers, grouped rows, and nested grids.",
5
5
  "main": "dist/arthub-table.common.js",
6
6
  "module": "dist/arthub-table.umd.min.js",
@@ -72,7 +72,6 @@
72
72
  "vue": "^3.0.0"
73
73
  },
74
74
  "dependencies": {
75
- "arthub-table": "0.0.5",
76
75
  "axios": "^1.6.0",
77
76
  "core-js": "^3.35.0",
78
77
  "gifuct-js": "^2.1.2",