@ai-table/grid 0.1.41-0 → 0.1.42

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 (71) hide show
  1. package/components/drag/drag.component.d.ts +1 -0
  2. package/components/drag/drag.component.d.ts.map +1 -1
  3. package/constants/colors.d.ts +4 -1
  4. package/constants/colors.d.ts.map +1 -1
  5. package/constants/icon.d.ts +1 -0
  6. package/constants/icon.d.ts.map +1 -1
  7. package/constants/table.d.ts +4 -0
  8. package/constants/table.d.ts.map +1 -1
  9. package/core/types/ai-table.d.ts +4 -1
  10. package/core/types/ai-table.d.ts.map +1 -1
  11. package/fesm2022/ai-table-grid.mjs +964 -299
  12. package/fesm2022/ai-table-grid.mjs.map +1 -1
  13. package/grid-base.component.d.ts +4 -2
  14. package/grid-base.component.d.ts.map +1 -1
  15. package/grid.component.d.ts +3 -1
  16. package/grid.component.d.ts.map +1 -1
  17. package/package.json +1 -1
  18. package/renderer/components/background.component.d.ts.map +1 -1
  19. package/renderer/components/cover-cell.component.d.ts.map +1 -1
  20. package/renderer/components/field-stat/stat.component.d.ts +13 -4
  21. package/renderer/components/field-stat/stat.component.d.ts.map +1 -1
  22. package/renderer/components/group/frozen-groups.component.d.ts +15 -0
  23. package/renderer/components/group/frozen-groups.component.d.ts.map +1 -0
  24. package/renderer/components/group/groups.component.d.ts +14 -0
  25. package/renderer/components/group/groups.component.d.ts.map +1 -0
  26. package/renderer/components/group/index.d.ts +3 -0
  27. package/renderer/components/group/index.d.ts.map +1 -0
  28. package/renderer/components/index.d.ts +2 -1
  29. package/renderer/components/index.d.ts.map +1 -1
  30. package/renderer/components/other-rows.component.d.ts.map +1 -1
  31. package/renderer/components/shadow.component.d.ts +10 -0
  32. package/renderer/components/shadow.component.d.ts.map +1 -0
  33. package/renderer/creations/create-cells.d.ts.map +1 -1
  34. package/renderer/creations/create-groups.d.ts +3 -0
  35. package/renderer/creations/create-groups.d.ts.map +1 -0
  36. package/renderer/creations/create-stats.d.ts +2 -1
  37. package/renderer/creations/create-stats.d.ts.map +1 -1
  38. package/renderer/drawers/cell-drawer.d.ts +1 -1
  39. package/renderer/drawers/cell-drawer.d.ts.map +1 -1
  40. package/renderer/drawers/drawer.d.ts +4 -1
  41. package/renderer/drawers/drawer.d.ts.map +1 -1
  42. package/renderer/drawers/group-layout.d.ts +11 -0
  43. package/renderer/drawers/group-layout.d.ts.map +1 -0
  44. package/renderer/drawers/layout-drawer.d.ts +5 -1
  45. package/renderer/drawers/layout-drawer.d.ts.map +1 -1
  46. package/renderer/drawers/record-row-layout-drawer.d.ts.map +1 -1
  47. package/renderer/renderer.component.d.ts +5 -0
  48. package/renderer/renderer.component.d.ts.map +1 -1
  49. package/types/cell.d.ts +12 -7
  50. package/types/cell.d.ts.map +1 -1
  51. package/types/component-config.d.ts +18 -3
  52. package/types/component-config.d.ts.map +1 -1
  53. package/types/layout.d.ts +2 -0
  54. package/types/layout.d.ts.map +1 -1
  55. package/types/row.d.ts +26 -7
  56. package/types/row.d.ts.map +1 -1
  57. package/utils/build.d.ts +1 -1
  58. package/utils/build.d.ts.map +1 -1
  59. package/utils/cell.d.ts +1 -0
  60. package/utils/cell.d.ts.map +1 -1
  61. package/utils/clipboard/paste.d.ts.map +1 -1
  62. package/utils/drag-fill/drag-fill.d.ts.map +1 -1
  63. package/utils/get-placeholder-cells.d.ts.map +1 -1
  64. package/utils/group.d.ts +3 -0
  65. package/utils/group.d.ts.map +1 -0
  66. package/utils/i18n.d.ts +3 -1
  67. package/utils/i18n.d.ts.map +1 -1
  68. package/utils/index.d.ts +1 -0
  69. package/utils/index.d.ts.map +1 -1
  70. package/renderer/components/frozen-field-shadow.component.d.ts +0 -14
  71. package/renderer/components/frozen-field-shadow.component.d.ts.map +0 -1
@@ -49,11 +49,11 @@ import { ThyInputNumber } from 'ngx-tethys/input-number';
49
49
  import { isKeyHotkey } from 'is-hotkey';
50
50
  import { LRUCache } from 'lru-cache';
51
51
  import { fromUnixTime, subDays, differenceInDays, differenceInMonths } from 'date-fns';
52
- import { isArray, TinyDate, helpers } from 'ngx-tethys/util';
52
+ import { isArray, TinyDate, helpers, hexToRgb } from 'ngx-tethys/util';
53
53
  import { DEFAULT_COLORS } from 'ngx-tethys/color-picker';
54
54
  import GraphemeSplitter from 'grapheme-splitter';
55
55
  import * as i1$2 from '@angular/common';
56
- import { CommonModule, NgClass, NgTemplateOutlet, NgComponentOutlet } from '@angular/common';
56
+ import { NgClass, CommonModule, NgTemplateOutlet, NgComponentOutlet } from '@angular/common';
57
57
  import { ThyDropdownAbstractMenu, ThyDropdownMenuItemDirective, ThyDropdownMenuComponent, ThyDropdownMenuGroup, ThyDropdownDirective, ThyDropdownMenuItemIconDirective, ThyDropdownMenuItemNameDirective, ThyDropdownMenuItemExtendIconDirective, ThyDropdownMenuItemMetaDirective } from 'ngx-tethys/dropdown';
58
58
  import { ThyEmptyModule } from 'ngx-tethys/empty';
59
59
  import { ThySelect, ThySelectModule } from 'ngx-tethys/select';
@@ -546,6 +546,7 @@ var AITableGridI18nKey;
546
546
  AITableGridI18nKey["selectedRecordsCount"] = "selectedRecordsCount";
547
547
  AITableGridI18nKey["selectedCellsCount"] = "selectedCellsCount";
548
548
  AITableGridI18nKey["stat"] = "stat";
549
+ AITableGridI18nKey["emptyGroup"] = "emptyGroup";
549
550
  })(AITableGridI18nKey || (AITableGridI18nKey = {}));
550
551
  const AITableGridI18nText = {
551
552
  [AITableGridI18nKey.dataPickerPlaceholder]: '选择日期',
@@ -598,7 +599,8 @@ const AITableGridI18nText = {
598
599
  [AITableGridI18nKey.dateRangeOfMonthsResult]: '时间范围 {{statValue}} 月',
599
600
  [AITableGridI18nKey.selectedRecordsCount]: '已经选择 {count} 条记录',
600
601
  [AITableGridI18nKey.selectedCellsCount]: '已经选择 {count} 个单元格',
601
- [AITableGridI18nKey.stat]: '统计'
602
+ [AITableGridI18nKey.stat]: '统计',
603
+ [AITableGridI18nKey.emptyGroup]: '(空)'
602
604
  };
603
605
  const getDefaultI18nTextByKey = (key) => {
604
606
  return AITableGridI18nText[key] || key;
@@ -752,9 +754,12 @@ const Colors = {
752
754
  gray100: '#f5f5f5',
753
755
  gray200: '#eee',
754
756
  gray300: '#ddd',
755
- gray800: '#333',
757
+ gray400: '#cacaca',
758
+ gray500: '#aaa',
756
759
  gray600: '#999',
757
760
  gray700: '#666',
761
+ gray800: '#333',
762
+ gray900: '#212529',
758
763
  white: '#fff',
759
764
  black: '#000',
760
765
  transparent: 'transparent',
@@ -822,6 +827,8 @@ var AITableRowType;
822
827
  (function (AITableRowType) {
823
828
  AITableRowType["add"] = "add";
824
829
  AITableRowType["record"] = "record";
830
+ AITableRowType["group"] = "group";
831
+ AITableRowType["blank"] = "blank";
825
832
  })(AITableRowType || (AITableRowType = {}));
826
833
 
827
834
  const AI_TABLE_ACTION_COMMON_SIZE = 32; // 表格图标action背景的通用尺寸
@@ -914,7 +921,11 @@ const AI_TABLE_AUTO_SCROLL_TOP_THRESHOLD = AI_TABLE_FIELD_HEAD_HEIGHT / 2;
914
921
  const AI_TABLE_AUTO_SCROLL_BOTTOM_THRESHOLD = AI_TABLE_FIELD_HEAD_HEIGHT / 2;
915
922
  const AI_TABLE_FIELD_STAT_INNER_HEIGHT = 47; // 字段统计内部高度
916
923
  const AI_TABLE_TEXT_LINE_HEIGHT = 1.84; // 默认文本行高
917
- const AI_TABLE_FIELD_STAT_CONTAINER_HEIGHT = AI_TABLE_FIELD_STAT_INNER_HEIGHT + AI_TABLE_OFFSET * 2; // 统计容器高度
924
+ const AI_TABLE_FIELD_STAT_CONTAINER_HEIGHT = AI_TABLE_FIELD_STAT_INNER_HEIGHT + AI_TABLE_CELL_LINE_BORDER * 2; // 统计容器高度
925
+ const AI_TABLE_GROUP_MAX_LEVEL = 3;
926
+ const AI_TABLE_ROW_GROUP_COLLAPSE_BUTTON = 'AI_TABLE_ROW_GROUP_COLLAPSE_BUTTON';
927
+ const AI_TABLE_ROW_GROUP_OFFSET = 16;
928
+ const AI_TABLE_SHADOW_DEFAULT_WIDTH = 8;
918
929
 
919
930
  const MIN_COLUMN_WIDTH = 80;
920
931
  const DBL_CLICK_EDIT_TYPE = [
@@ -979,6 +990,7 @@ const AttachmentPath = `M9.1773124,11.8057395 C7.96668709,13.0163648 6.00387566,
979
990
  const EditPath = `M2,8.33918294 L10.7095952,0 L15,4.17020474 L6.53816398,13 L2,13 L2,8.33918294 Z M3.2,8.85157902 L3.2,11.8 L6.02608482,11.8 L13.3091776,4.20020516 L10.7033283,1.66736141 L3.2,8.85157902 Z M0,16 L0,14.8 L16,14.8 L16,16 L0,16 Z`;
980
991
  const RowDragPath = `M6,3 C6.55228475,3 7,2.55228475 7,2 C7,1.44771525 6.55228475,1 6,1 C5.44771525,1 5,1.44771525 5,2 C5,2.55228475 5.44771525,3 6,3 Z M10,3 C10.5522847,3 11,2.55228475 11,2 C11,1.44771525 10.5522847,1 10,1 C9.44771525,1 9,1.44771525 9,2 C9,2.55228475 9.44771525,3 10,3 Z M6,7 C6.55228475,7 7,6.55228475 7,6 C7,5.44771525 6.55228475,5 6,5 C5.44771525,5 5,5.44771525 5,6 C5,6.55228475 5.44771525,7 6,7 Z M10,7 C10.5522847,7 11,6.55228475 11,6 C11,5.44771525 10.5522847,5 10,5 C9.44771525,5 9,5.44771525 9,6 C9,6.55228475 9.44771525,7 10,7 Z M6,11 C6.55228475,11 7,10.5522847 7,10 C7,9.44771525 6.55228475,9 6,9 C5.44771525,9 5,9.44771525 5,10 C5,10.5522847 5.44771525,11 6,11 Z M10,11 C10.5522847,11 11,10.5522847 11,10 C11,9.44771525 10.5522847,9 10,9 C9.44771525,9 9,9.44771525 9,10 C9,10.5522847 9.44771525,11 10,11 Z M6,15 C6.55228475,15 7,14.5522847 7,14 C7,13.4477153 6.55228475,13 6,13 C5.44771525,13 5,13.4477153 5,14 C5,14.5522847 5.44771525,15 6,15 Z M10,15 C10.5522847,15 11,14.5522847 11,14 C11,13.4477153 10.5522847,13 10,13 C9.44771525,13 9,13.4477153 9,14 C9,14.5522847 9.44771525,15 10,15 Z`;
981
992
  const AngleDownPath = `M7.97815,11.99732 L7.9728,12.00267 L2.2998,6.33067 L3.1298,5.49967 L7.97807731,10.3479473 L12.8255,5.49967 L13.6565,6.33067 L7.9835,12.00267 L7.97815,11.99732 Z`;
993
+ const AngleRightPath = `M4.72665,3.40415 L5.55765,2.57315 L11.22965,8.24615 L5.55765,13.92985 L4.72665,13.09985 L9.57465,8.25285`;
982
994
  const IconPathMap = {};
983
995
 
984
996
  const DEFAULT_FONT_SIZE = 14;
@@ -1947,8 +1959,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
1947
1959
  args: ['inputElement', { static: false }]
1948
1960
  }] } });
1949
1961
 
1950
- const buildGridLinearRows = (visibleRecords, isAddingVisible = true) => {
1951
- const linearRows = [];
1962
+ const buildGridLinearRows = (visibleRecords, isAddingVisible = true, aiTable, aiBuildGroupLinearRowsFn) => {
1963
+ let linearRows = [];
1964
+ if (aiBuildGroupLinearRowsFn) {
1965
+ const groupLinearRows = aiBuildGroupLinearRowsFn(aiTable);
1966
+ if (groupLinearRows) {
1967
+ return groupLinearRows;
1968
+ }
1969
+ }
1952
1970
  let displayRowIndex = 0;
1953
1971
  [...visibleRecords, { _id: '' }].forEach((row) => {
1954
1972
  if (row._id) {
@@ -1956,13 +1974,15 @@ const buildGridLinearRows = (visibleRecords, isAddingVisible = true) => {
1956
1974
  linearRows.push({
1957
1975
  type: AITableRowType.record,
1958
1976
  _id: row._id,
1959
- displayIndex: displayRowIndex
1977
+ displayIndex: displayRowIndex,
1978
+ depth: 0
1960
1979
  });
1961
1980
  }
1962
1981
  if (isAddingVisible && !row._id) {
1963
1982
  linearRows.push({
1964
1983
  type: AITableRowType.add,
1965
- _id: ''
1984
+ _id: '',
1985
+ depth: 0
1966
1986
  });
1967
1987
  }
1968
1988
  });
@@ -1997,8 +2017,18 @@ function getColumnIndicesSizeMap(aiTable, fields) {
1997
2017
  * 根据单元格是否是第一列/最后一列确定单元格所在的位置
1998
2018
  */
1999
2019
  function getCellHorizontalPosition(options) {
2000
- const { columnWidth } = options;
2001
- return { width: columnWidth, offset: 0 };
2020
+ let { columnWidth, columnIndex, columnCount, depth = 0 } = options;
2021
+ depth += 1;
2022
+ if (!depth)
2023
+ return { width: columnWidth, offset: 0 };
2024
+ const firstIndent = columnIndex === 0 && depth;
2025
+ const lastIndent = columnIndex === columnCount - 1 && depth === 3;
2026
+ const offset = firstIndent ? (depth - 1) * AI_TABLE_ROW_GROUP_OFFSET + 0.5 : 0;
2027
+ const width = lastIndent && !firstIndent ? columnWidth - AI_TABLE_ROW_GROUP_OFFSET : columnWidth - offset;
2028
+ return {
2029
+ width,
2030
+ offset
2031
+ };
2002
2032
  }
2003
2033
  function transformToCellText(cellValue, options) {
2004
2034
  const { aiTable, field } = options;
@@ -2121,7 +2151,13 @@ function selectCells(aiTable, startCell, endCell, activeCell) {
2121
2151
  selectedCells.add(`${startRecordId}:${startFieldId}`);
2122
2152
  }
2123
2153
  else {
2124
- if (endCell && endCell.join(':') === aiTable.selection().selectedEndCell?.join(':')) {
2154
+ const startCellPath = startCell.join(':');
2155
+ const endCellPath = endCell.join(':');
2156
+ const selectCells = Array.from(aiTable.selection().selectedCells);
2157
+ const startSelectedCellPath = selectCells[0];
2158
+ const endSelectedCellPath = selectCells[selectCells.length - 1];
2159
+ if ((startCellPath === startSelectedCellPath || startCellPath === endSelectedCellPath) &&
2160
+ (endCellPath === startSelectedCellPath || endCellPath === endSelectedCellPath)) {
2125
2161
  return;
2126
2162
  }
2127
2163
  const [endRecordId, endFieldId] = endCell;
@@ -2134,8 +2170,11 @@ function selectCells(aiTable, startCell, endCell, activeCell) {
2134
2170
  const minColIndex = Math.min(startColIndex, endColIndex);
2135
2171
  const maxColIndex = Math.max(startColIndex, endColIndex);
2136
2172
  for (let i = minRowIndex; i <= maxRowIndex; i++) {
2137
- for (let j = minColIndex; j <= maxColIndex; j++) {
2138
- selectedCells.add(`${records[i]._id}:${fields[j]._id}`);
2173
+ const row = records[i];
2174
+ if (row && row.type === AITableRowType.record) {
2175
+ for (let j = minColIndex; j <= maxColIndex; j++) {
2176
+ selectedCells.add(`${row._id}:${fields[j]._id}`);
2177
+ }
2139
2178
  }
2140
2179
  }
2141
2180
  }
@@ -2237,7 +2276,7 @@ function getPlaceHolderCellsConfigs(options) {
2237
2276
  break;
2238
2277
  }
2239
2278
  const row = linearRows()[rowIndex];
2240
- const { _id: recordId, type } = row;
2279
+ const { _id: recordId, type, depth = 0 } = row;
2241
2280
  if (type !== AITableRowType.record) {
2242
2281
  continue;
2243
2282
  }
@@ -2246,7 +2285,8 @@ function getPlaceHolderCellsConfigs(options) {
2246
2285
  const { width, offset } = getCellHorizontalPosition({
2247
2286
  columnWidth,
2248
2287
  columnIndex,
2249
- columnCount
2288
+ columnCount,
2289
+ depth
2250
2290
  });
2251
2291
  const height = rowHeight - AI_TABLE_OFFSET * 4;
2252
2292
  configs.unshift({
@@ -3500,6 +3540,20 @@ function buildClipboardContent(aiTable, fieldIds, recordIds) {
3500
3540
  return clipboardContent;
3501
3541
  }
3502
3542
 
3543
+ function getGroupLastRecordIndex(aiTable, startRowIndex) {
3544
+ const linearRows = aiTable.context.linearRows();
3545
+ if (startRowIndex + 1 >= linearRows.length) {
3546
+ return startRowIndex;
3547
+ }
3548
+ for (let i = startRowIndex + 1; i < linearRows.length; i++) {
3549
+ const row = linearRows[i];
3550
+ if (row.type !== AITableRowType.record) {
3551
+ return i - 1;
3552
+ }
3553
+ }
3554
+ return linearRows.length - 1;
3555
+ }
3556
+
3503
3557
  const aiTableAttributePattern = new RegExp(`${aiTableFragmentAttribute}="(.+?)"`, 'm');
3504
3558
  const decodeClipboardJsonData = (encoded) => {
3505
3559
  const decoded = decodeURIComponent(window.atob(encoded));
@@ -3645,14 +3699,20 @@ const writeToAITable = async (aiTable, actions) => {
3645
3699
  const maxFields = aiTable.context.maxFields();
3646
3700
  const maxRecords = aiTable.context.maxRecords();
3647
3701
  const startRowIndex = aiTable.context.visibleRowsIndexMap().get(startRecordId) ?? 0;
3648
- const lastRowIndex = aiTable.context.linearRows().length - 1;
3702
+ const lastRowIndex = getGroupLastRecordIndex(aiTable, startRowIndex);
3703
+ let appendRowCount = clipboardContent.length - (lastRowIndex - startRowIndex) - 1;
3649
3704
  const recordsCount = aiTable.records().length;
3650
- let appendRowCount = clipboardContent.length - (lastRowIndex - startRowIndex);
3651
3705
  if (maxRecords && recordsCount + appendRowCount > maxRecords) {
3652
3706
  appendRowCount = maxRecords - recordsCount;
3653
3707
  result.isPasteOverMaxRecords = true;
3654
3708
  }
3655
- actions.addRecord({ count: appendRowCount });
3709
+ if (appendRowCount > 0) {
3710
+ actions.addRecord({
3711
+ count: appendRowCount,
3712
+ afterRecordId: startRecordId,
3713
+ forGroupId: startRecordId
3714
+ });
3715
+ }
3656
3716
  const startColIndex = aiTable.context.visibleColumnsIndexMap().get(startFieldId) ?? 0;
3657
3717
  const lastColIndex = aiTable.context.visibleColumnsIndexMap().size - 1;
3658
3718
  const copiedFieldLength = clipboardContent[0].length;
@@ -3676,12 +3736,12 @@ const writeToAITable = async (aiTable, actions) => {
3676
3736
  if (maxRecords && targetRowIndex >= maxRecords) {
3677
3737
  return;
3678
3738
  }
3739
+ const targetRecord = linearRows[targetRowIndex];
3679
3740
  row.forEach((plainText, j) => {
3680
3741
  const targetColIndex = startColIndex + j;
3681
3742
  if (maxFields && targetColIndex >= maxFields) {
3682
3743
  return;
3683
3744
  }
3684
- const targetRecord = linearRows[targetRowIndex];
3685
3745
  const targetField = visibleFields[targetColIndex];
3686
3746
  const recordIndex = i;
3687
3747
  const fieldIndex = j;
@@ -5449,13 +5509,15 @@ class Layout extends Drawer {
5449
5509
  // 列数
5450
5510
  this.columnCount = 0;
5451
5511
  this.containerWidth = 0;
5512
+ this.frozenColumnCount = 0;
5452
5513
  this.rowHeadWidth = AI_TABLE_ROW_HEAD_WIDTH_AND_DRAG_ICON_WIDTH;
5453
5514
  this.hiddenIndexColumn = false;
5454
5515
  this.hiddenRowDrag = false;
5455
5516
  this.readonly = false;
5517
+ this.xIsScroll = false;
5456
5518
  }
5457
5519
  // 用于初始化或重置布局的基本属性。这个方法通常在每次渲染新的一行或单元格时调用,确保布局信息是最新的
5458
- init({ x, y, rowIndex, columnIndex, rowHeight, columnWidth, columnCount, containerWidth, rowHeadWidth, hiddenIndexColumn, hiddenRowDrag, readonly }) {
5520
+ init({ x, y, rowIndex, columnIndex, rowHeight, columnWidth, columnCount, containerWidth, rowHeadWidth, hiddenIndexColumn, hiddenRowDrag, readonly, frozenColumnCount, xIsScroll }) {
5459
5521
  this.x = x;
5460
5522
  this.y = y;
5461
5523
  this.rowIndex = rowIndex;
@@ -5468,11 +5530,17 @@ class Layout extends Drawer {
5468
5530
  this.hiddenIndexColumn = hiddenIndexColumn;
5469
5531
  this.hiddenRowDrag = hiddenRowDrag;
5470
5532
  this.readonly = readonly;
5533
+ this.frozenColumnCount = frozenColumnCount;
5534
+ this.xIsScroll = xIsScroll;
5471
5535
  }
5472
5536
  // 当前单元格是否是行的第一列
5473
5537
  get isFirst() {
5474
5538
  return this.columnIndex === 0;
5475
5539
  }
5540
+ // 当前单元格是否是锁定列的最后一列
5541
+ get isLastFrozenColumn() {
5542
+ return this.columnIndex === this.frozenColumnCount - 1;
5543
+ }
5476
5544
  // 当前单元格是否是行的最后一列
5477
5545
  get isLast() {
5478
5546
  return this.columnIndex === this.columnCount - 1;
@@ -5491,6 +5559,22 @@ class Layout extends Drawer {
5491
5559
  fill
5492
5560
  });
5493
5561
  }
5562
+ renderFrozenShadow() {
5563
+ if (this.isLastFrozenColumn && this.xIsScroll) {
5564
+ const shadowWidth = AI_TABLE_SHADOW_DEFAULT_WIDTH;
5565
+ const shadowGradient = this.ctx.createLinearGradient(this.x + this.columnWidth + 0, this.y, this.x + this.columnWidth + 0 + shadowWidth, this.y);
5566
+ // 阴影从分割线处最深,逐渐变浅
5567
+ shadowGradient.addColorStop(0, 'rgba(0,0,0,0.05)');
5568
+ shadowGradient.addColorStop(1, this.colors.transparent);
5569
+ this.rect({
5570
+ x: this.x + this.columnWidth + 0,
5571
+ y: this.y,
5572
+ width: shadowWidth,
5573
+ height: this.rowHeight,
5574
+ fill: shadowGradient
5575
+ });
5576
+ }
5577
+ }
5494
5578
  }
5495
5579
 
5496
5580
  class AddRowLayout extends Layout {
@@ -6858,10 +6942,108 @@ class RecordRowLayout extends Layout {
6858
6942
  this.renderFirstCell({ row, style, indexStyle, isCheckedRow, isHoverRow });
6859
6943
  this.renderCommonCell({ style });
6860
6944
  this.renderLastCell({ style, isCheckedRow, isHoverRow });
6945
+ this.renderFrozenShadow();
6861
6946
  }
6862
6947
  }
6863
6948
  const recordRowLayout = new RecordRowLayout();
6864
6949
 
6950
+ class GroupLayout extends Layout {
6951
+ renderAddFieldBlank({ isHoverRow, isCheckedRow }) {
6952
+ super.renderAddFieldBlank({ isHoverRow, isCheckedRow });
6953
+ const rowHeight = this.rowHeight;
6954
+ const startX = this.x + this.columnWidth;
6955
+ const lineWidth = this.containerWidth - startX < AI_TABLE_FIELD_ADD_BUTTON_WIDTH ? AI_TABLE_FIELD_ADD_BUTTON_WIDTH : this.containerWidth - startX;
6956
+ this.line({
6957
+ x: startX,
6958
+ y: this.y,
6959
+ points: [0, rowHeight, lineWidth, rowHeight],
6960
+ stroke: this.colors.gray200
6961
+ });
6962
+ }
6963
+ renderFirstCell(render, config) {
6964
+ if (!this.isFirst)
6965
+ return;
6966
+ const { row, indexStyle } = config;
6967
+ const { _id: recordId, type, depth = 0, groupValue, fieldId, isCollapsed } = row;
6968
+ const { field, style, aiTable } = render;
6969
+ const y = this.y;
6970
+ const rowHeight = this.rowHeight;
6971
+ const columnWidth = this.columnWidth;
6972
+ const { fill: indexFill } = indexStyle || {};
6973
+ const dragOccupyWidth = this.hiddenRowDrag || this.readonly ? 0 : AI_TABLE_ROW_DRAG_ICON_WIDTH;
6974
+ if (!this.hiddenIndexColumn) {
6975
+ this.customRect({
6976
+ x: AI_TABLE_OFFSET + dragOccupyWidth,
6977
+ y,
6978
+ width: this.rowHeadWidth - AI_TABLE_OFFSET - dragOccupyWidth,
6979
+ height: rowHeight,
6980
+ fill: indexFill,
6981
+ strokes: {
6982
+ top: this.colors.gray200,
6983
+ bottom: this.colors.gray200
6984
+ }
6985
+ });
6986
+ // 第一列单元格
6987
+ this.rect({
6988
+ x: AI_TABLE_CELL_PADDING + dragOccupyWidth + 2,
6989
+ y: this.y + (rowHeight - AI_TABLE_ICON_COMMON_SIZE) / 2,
6990
+ width: AI_TABLE_ICON_COMMON_SIZE,
6991
+ height: AI_TABLE_ICON_COMMON_SIZE,
6992
+ fill: hexToRgb(this.colors.gray400, 0.2),
6993
+ stroke: this.colors.gray300,
6994
+ radius: 2
6995
+ });
6996
+ }
6997
+ const iconContainerWidth = AI_TABLE_ICON_COMMON_SIZE + AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE;
6998
+ if (!isEmpty(groupValue)) {
6999
+ cellDrawer.initStyle(field, style);
7000
+ cellDrawer.renderCell({
7001
+ ...render,
7002
+ x: render.x + iconContainerWidth,
7003
+ columnWidth: render.columnWidth - iconContainerWidth
7004
+ }, this.ctx, columnWidth);
7005
+ }
7006
+ else {
7007
+ const emptyGroupString = getI18nTextByKey(aiTable, AITableGridI18nKey.emptyGroup);
7008
+ this.text({
7009
+ x: render.x + iconContainerWidth + AI_TABLE_CELL_PADDING,
7010
+ y: this.y + (rowHeight - AI_TABLE_COMMON_FONT_SIZE) / 2,
7011
+ text: emptyGroupString
7012
+ });
7013
+ }
7014
+ }
7015
+ renderCommonCellBorder({ style }) {
7016
+ const { fill, stroke } = style || {};
7017
+ const colors = AITable.getColors();
7018
+ // 背景、边框
7019
+ this.customRect({
7020
+ x: this.x,
7021
+ y: this.y,
7022
+ width: this.columnWidth,
7023
+ height: this.rowHeight,
7024
+ fill: fill || colors.white,
7025
+ strokes: {
7026
+ top: stroke || colors.gray200,
7027
+ bottom: stroke || colors.gray200,
7028
+ right: this.isLastFrozenColumn ? this.colors.gray200 : undefined
7029
+ }
7030
+ });
7031
+ }
7032
+ renderLastCell({ style, isHoverRow, isCheckedRow }) {
7033
+ if (this.isLast) {
7034
+ this.renderAddFieldBlank({ isHoverRow: false, isCheckedRow: false });
7035
+ }
7036
+ }
7037
+ render(render, config) {
7038
+ const { style, isHoverRow, isCheckedRow } = config;
7039
+ this.renderFirstCell(render, config);
7040
+ this.renderCommonCellBorder({ style });
7041
+ this.renderLastCell({ style, isHoverRow, isCheckedRow });
7042
+ this.renderFrozenShadow();
7043
+ }
7044
+ }
7045
+ const groupLayout = new GroupLayout();
7046
+
6865
7047
  /**
6866
7048
  * 绘制单元格内容的函数
6867
7049
  * 利用 Canvas API 绘制每个单元格的背景颜色、文本以及其他可能的样式。这个函数通常用于自定义表格渲染,尤其是在处理大量数据时,通过直接操作 Canvas 来提高渲染性能
@@ -6873,11 +7055,14 @@ const createCells = (config) => {
6873
7055
  const { rowHeight, columnCount, rowCount } = coordinate;
6874
7056
  const colors = AITable.getColors();
6875
7057
  const visibleColumns = AITable.getVisibleFields(aiTable);
7058
+ const xIsScroll = aiTable.context.scrollState().scrollLeft > 0;
6876
7059
  // 初始化绘图上下文, 为后续的绘制操作做准备
6877
7060
  cellDrawer.initCtx(ctx);
6878
7061
  addRowLayout.initCtx(ctx);
6879
7062
  recordRowLayout.initCtx(ctx);
7063
+ groupLayout.initCtx(ctx);
6880
7064
  const coverCell = getCoverCell(aiTable);
7065
+ const frozenColumnCount = aiTable.context?.frozenColumnCount() || 1;
6881
7066
  // 遍历列, 确定在哪些列上绘制单元格
6882
7067
  for (let columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) {
6883
7068
  if (columnIndex > columnCount - 1)
@@ -6898,7 +7083,7 @@ const createCells = (config) => {
6898
7083
  if (rowIndex > rowCount - 1)
6899
7084
  break;
6900
7085
  const row = context.linearRows()[rowIndex];
6901
- const { _id: recordId, type } = row;
7086
+ const { _id: recordId, type, depth = 0 } = row;
6902
7087
  const y = coordinate.getRowOffset(rowIndex) + AI_TABLE_OFFSET;
6903
7088
  const { rowIndex: pointRowIndex, targetName } = context.pointPosition();
6904
7089
  const isHover = pointRowIndex === rowIndex;
@@ -6918,7 +7103,8 @@ const createCells = (config) => {
6918
7103
  rowHeadWidth: context.rowHeadWidth(),
6919
7104
  hiddenIndexColumn: !!context.aiFieldConfig()?.hiddenIndexColumn,
6920
7105
  hiddenRowDrag: !!context.aiFieldConfig()?.hiddenRowDrag,
6921
- readonly: aiTable.context?.readonly?.()
7106
+ readonly: aiTable.context?.readonly?.(),
7107
+ frozenColumnCount
6922
7108
  });
6923
7109
  addRowLayout.render({
6924
7110
  isHoverRow,
@@ -6944,7 +7130,9 @@ const createCells = (config) => {
6944
7130
  rowHeadWidth: context.rowHeadWidth(),
6945
7131
  hiddenIndexColumn: !!context.aiFieldConfig()?.hiddenIndexColumn,
6946
7132
  hiddenRowDrag: !!context.aiFieldConfig()?.hiddenRowDrag,
6947
- readonly: aiTable.context?.readonly?.()
7133
+ readonly: aiTable.context?.readonly?.(),
7134
+ frozenColumnCount,
7135
+ xIsScroll
6948
7136
  });
6949
7137
  recordRowLayout.render({
6950
7138
  row,
@@ -6953,12 +7141,17 @@ const createCells = (config) => {
6953
7141
  isHoverRow: isHoverRecord(isHover, targetName),
6954
7142
  isCheckedRow: isSelectedRecord(recordId, aiTable)
6955
7143
  });
7144
+ const isGroupAndFirstColumn = depth > 0 && columnIndex === 0;
6956
7145
  const { width, offset } = getCellHorizontalPosition({
6957
7146
  columnIndex,
6958
- columnWidth,
6959
- columnCount
7147
+ columnWidth: isGroupAndFirstColumn ? columnWidth - AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE : columnWidth,
7148
+ columnCount,
7149
+ depth
6960
7150
  });
6961
- const realX = x + offset + AI_TABLE_OFFSET;
7151
+ let realX = x + offset + AI_TABLE_OFFSET;
7152
+ if (isGroupAndFirstColumn) {
7153
+ realX += AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE;
7154
+ }
6962
7155
  const realY = y + AI_TABLE_OFFSET;
6963
7156
  const style = { fontWeight: DEFAULT_FONT_STYLE };
6964
7157
  const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, fieldId]);
@@ -6999,6 +7192,60 @@ const createCells = (config) => {
6999
7192
  else {
7000
7193
  cellDrawer.renderCell(render, ctx, columnWidth);
7001
7194
  }
7195
+ break;
7196
+ }
7197
+ case AITableRowType.group: {
7198
+ const fieldId = row.fieldId;
7199
+ const field = aiTable.fieldsMap()[fieldId];
7200
+ groupLayout.init({
7201
+ x,
7202
+ y,
7203
+ rowIndex,
7204
+ columnIndex,
7205
+ columnWidth,
7206
+ rowHeight,
7207
+ columnCount,
7208
+ containerWidth: coordinate.containerWidth,
7209
+ rowHeadWidth: context.rowHeadWidth(),
7210
+ hiddenIndexColumn: !!context.aiFieldConfig()?.hiddenIndexColumn,
7211
+ hiddenRowDrag: !!context.aiFieldConfig()?.hiddenRowDrag,
7212
+ readonly: aiTable.context?.readonly?.(),
7213
+ frozenColumnCount,
7214
+ xIsScroll
7215
+ });
7216
+ const { width, offset } = getCellHorizontalPosition({
7217
+ columnIndex,
7218
+ columnWidth,
7219
+ columnCount,
7220
+ depth
7221
+ });
7222
+ const realX = x + offset + AI_TABLE_OFFSET;
7223
+ const realY = y + AI_TABLE_OFFSET;
7224
+ const style = { fontWeight: DEFAULT_FONT_STYLE };
7225
+ const cellValue = row.groupValue;
7226
+ const fieldModel = FieldModelMap[field.type];
7227
+ const transformValue = fieldModel.transformCellValue(cellValue, { aiTable, field });
7228
+ const render = {
7229
+ aiTable,
7230
+ x: realX,
7231
+ y: realY,
7232
+ columnWidth: width,
7233
+ rowHeight,
7234
+ recordId: recordId,
7235
+ field,
7236
+ cellValue,
7237
+ transformValue,
7238
+ references,
7239
+ isActive: isSelectedField(fieldId, aiTable),
7240
+ style,
7241
+ colors,
7242
+ isCoverCell: false
7243
+ };
7244
+ groupLayout.render(render, {
7245
+ row: row,
7246
+ isHoverRow: isHoverRecord(isHover, targetName),
7247
+ isCheckedRow: isSelectedRecord(recordId, aiTable)
7248
+ });
7002
7249
  }
7003
7250
  }
7004
7251
  }
@@ -7992,9 +8239,10 @@ class AITableOtherRows {
7992
8239
  break;
7993
8240
  if (maxRecords && aiTable.records().length >= maxRecords)
7994
8241
  break;
7995
- const { _id, type } = aiTable.context.linearRows()[rowIndex];
7996
- if (type === AITableRowType.record)
8242
+ const linearRow = aiTable.context.linearRows()[rowIndex];
8243
+ if (linearRow.type === AITableRowType.record)
7997
8244
  continue;
8245
+ const { _id, type } = linearRow;
7998
8246
  const y = coordinate.getRowOffset(rowIndex);
7999
8247
  const curHeight = coordinate.getRowHeight(rowIndex);
8000
8248
  otherRowConfigs.push({
@@ -8002,7 +8250,10 @@ class AITableOtherRows {
8002
8250
  addBtnConfig: {
8003
8251
  key: `row-add-${_id}`,
8004
8252
  y: y + 1,
8005
- name: AI_TABLE_ROW_ADD_BUTTON,
8253
+ name: generateTargetName({
8254
+ targetName: AI_TABLE_ROW_ADD_BUTTON,
8255
+ source: _id
8256
+ }),
8006
8257
  width: coordinate.containerWidth,
8007
8258
  height: curHeight - 1,
8008
8259
  fill: 'transparent'
@@ -8151,14 +8402,17 @@ class AITableBackground {
8151
8402
  return { x, y };
8152
8403
  });
8153
8404
  this.bgConfig = computed(() => {
8154
- const { name, width, height, fill = Colors.transparent, cornerRadius, opacity, hoverFill, hoverOpacity, listening } = this.config();
8405
+ const { name, width, height, fill = Colors.transparent, opacity, hoverFill, hoverOpacity, listening, borders } = this.config();
8406
+ const [top, right, bottom, left] = borders || [false, false, false, false];
8155
8407
  const active = this.isHover() || this.isActive();
8408
+ const strokeWidth = this.strokeWidth() || AI_TABLE_OFFSET;
8156
8409
  const result = {
8410
+ x: left ? 0 : strokeWidth,
8411
+ y: top ? 0 : strokeWidth,
8412
+ width: width - (left ? 0 : strokeWidth) - (right ? 0 : strokeWidth),
8413
+ height: height - (top ? 0 : strokeWidth) - (bottom ? 0 : strokeWidth),
8157
8414
  name,
8158
- width,
8159
- height,
8160
8415
  fill: active ? hoverFill || fill : fill,
8161
- cornerRadius,
8162
8416
  opacity: active ? hoverOpacity || opacity : opacity,
8163
8417
  listening
8164
8418
  };
@@ -8236,46 +8490,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
8236
8490
  }]
8237
8491
  }] });
8238
8492
 
8239
- class AITableFrozenFieldShadow {
8493
+ class AITableShadow {
8240
8494
  constructor() {
8241
8495
  this.config = input.required();
8242
- this.position = input('table');
8243
- this.coordinate = computed(() => {
8244
- return this.config().coordinate;
8245
- });
8246
- this.scrollState = computed(() => {
8247
- return this.config().aiTable.context.scrollState();
8248
- });
8249
- this.frozenAreaWidth = computed(() => {
8250
- return this.config().aiTable.context.rowHeadWidth() + this.config().coordinate.frozenColumnWidth;
8251
- });
8252
- this.frozenShadowConfig = computed(() => {
8253
- const { aiTable } = this.config();
8254
- const coordinate = this.coordinate();
8255
- const rowCount = aiTable.gridData().records.length;
8256
- const height = this.position() !== 'fieldStats'
8257
- ? rowCount * coordinate.rowHeight + AI_TABLE_FIELD_HEAD_HEIGHT
8258
- : this.config().height;
8496
+ this.shadowConfig = computed(() => {
8497
+ const { visible, x, y, width = AI_TABLE_SHADOW_DEFAULT_WIDTH, height } = this.config();
8259
8498
  return {
8260
- visible: this.scrollState().scrollLeft > 0,
8261
- x: this.frozenAreaWidth() + 1, // 偏移1,避免和边框重叠导致颜色太深
8262
- y: 0,
8263
- width: 8,
8499
+ visible,
8500
+ x,
8501
+ y,
8502
+ width,
8264
8503
  height,
8265
8504
  fillLinearGradientStartPoint: { x: 0, y: 0 },
8266
- fillLinearGradientEndPoint: { x: 8, y: 0 },
8505
+ fillLinearGradientEndPoint: { x: width, y: 0 },
8267
8506
  fillLinearGradientColorStops: [0, 'rgba(0,0,0,0.05)', 1, Colors.transparent]
8268
8507
  };
8269
8508
  });
8270
8509
  }
8271
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableFrozenFieldShadow, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8272
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.10", type: AITableFrozenFieldShadow, isStandalone: true, selector: "ai-table-frozen-field-shadow", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `<ko-rect [config]="frozenShadowConfig()"></ko-rect>`, isInline: true, dependencies: [{ kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8510
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableShadow, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8511
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.10", type: AITableShadow, isStandalone: true, selector: "ai-table-shadow", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `<ko-rect [config]="shadowConfig()"></ko-rect>`, isInline: true, dependencies: [{ kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8273
8512
  }
8274
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableFrozenFieldShadow, decorators: [{
8513
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableShadow, decorators: [{
8275
8514
  type: Component,
8276
8515
  args: [{
8277
- selector: 'ai-table-frozen-field-shadow',
8278
- template: `<ko-rect [config]="frozenShadowConfig()"></ko-rect>`,
8516
+ selector: 'ai-table-shadow',
8517
+ template: `<ko-rect [config]="shadowConfig()"></ko-rect>`,
8279
8518
  imports: [KoShape],
8280
8519
  changeDetection: ChangeDetectionStrategy.OnPush
8281
8520
  }]
@@ -8727,177 +8966,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
8727
8966
  args: ['rootGroup']
8728
8967
  }] } });
8729
8968
 
8730
- class AITableFillHandle {
8731
- constructor() {
8732
- this.config = input.required();
8733
- this.showFillHandle = computed(() => {
8734
- const { aiTable, readonly } = this.config();
8735
- const selection = aiTable.selection();
8736
- const hasSelectedCells = selection.selectedCells.size > 0;
8737
- const isEditingCell = !!aiTable.editingCell()?.path;
8738
- return hasSelectedCells && !readonly && !isEditingCell;
8739
- });
8740
- this.handleConfig = computed(() => {
8741
- const { aiTable, coordinate } = this.config();
8742
- const selectedCells = Array.from(aiTable.selection().selectedCells);
8743
- const lastCell = selectedCells[selectedCells.length - 1];
8744
- const [recordId, fieldId] = lastCell.split(':');
8745
- const columnIndex = aiTable.context.visibleColumnsIndexMap().get(fieldId);
8746
- const columnOffset = coordinate.getColumnOffset(columnIndex);
8747
- const columnWidth = coordinate.getColumnWidth(columnIndex);
8748
- const rowIndex = aiTable.context.visibleRowsIndexMap().get(recordId);
8749
- const rowOffset = coordinate.getRowOffset(rowIndex);
8750
- const width = 6;
8751
- const height = 6;
8752
- const [expandRecordId, expandFieldId] = aiTable.expendCell()?.path || [null, null];
8753
- const cellHeight = expandRecordId === recordId && expandFieldId === fieldId && aiTable.expendCell()?.height
8754
- ? aiTable.expendCell()?.height
8755
- ? aiTable.expendCell().height + AI_TABLE_CELL_LINE_BORDER
8756
- : AI_TABLE_ROW_HEIGHT
8757
- : AI_TABLE_ROW_HEIGHT;
8758
- return {
8759
- x: columnOffset + columnWidth - width / 2 + AI_TABLE_OFFSET,
8760
- y: rowOffset + cellHeight - height + AI_TABLE_CELL_BORDER + AI_TABLE_OFFSET,
8761
- width,
8762
- height,
8763
- fill: Colors.primary,
8764
- stroke: Colors.white,
8765
- strokeWidth: 2,
8766
- zIndex: 20,
8767
- name: generateTargetName({
8768
- targetName: AI_TABLE_FILL_HANDLE,
8769
- fieldId,
8770
- recordId
8771
- })
8772
- };
8969
+ const createGroupCells = (config) => {
8970
+ const { coordinate, rowStartIndex, rowStopIndex, columnStartIndex, columnStopIndex, aiTable, actions, readonly } = config;
8971
+ const linearRows = aiTable.context?.linearRows();
8972
+ const { columnCount } = coordinate;
8973
+ const groups = [];
8974
+ for (let rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) {
8975
+ if (rowIndex > columnCount - 1)
8976
+ break;
8977
+ if (rowIndex < 0)
8978
+ continue;
8979
+ const row = linearRows[rowIndex];
8980
+ const { depth } = row;
8981
+ if (row == null)
8982
+ continue;
8983
+ if (row.type !== AITableRowType.group)
8984
+ continue;
8985
+ const y = coordinate.getRowOffset(rowIndex) + AI_TABLE_OFFSET;
8986
+ const rowHeight = coordinate.getRowHeight(rowIndex);
8987
+ const columnWidth = coordinate.getColumnWidth(columnStartIndex);
8988
+ const { offset } = getCellHorizontalPosition({
8989
+ columnIndex: columnStartIndex,
8990
+ columnWidth,
8991
+ columnCount,
8992
+ depth
8773
8993
  });
8994
+ const x = coordinate.getColumnOffset(columnStartIndex);
8995
+ const group = {
8996
+ aiTable,
8997
+ coordinate,
8998
+ rowIndex,
8999
+ x: x + offset + AI_TABLE_CELL_PADDING,
9000
+ y,
9001
+ height: rowHeight,
9002
+ row: {
9003
+ ...row,
9004
+ rowIndex
9005
+ },
9006
+ readonly
9007
+ };
9008
+ groups.push(group);
8774
9009
  }
8775
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableFillHandle, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8776
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableFillHandle, isStandalone: true, selector: "ai-table-fill-handle", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
8777
- @if (showFillHandle()) {
8778
- <ko-rect [config]="handleConfig()"></ko-rect>
8779
- }
8780
- `, isInline: true, dependencies: [{ kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }] }); }
8781
- }
8782
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableFillHandle, decorators: [{
8783
- type: Component,
8784
- args: [{
8785
- selector: 'ai-table-fill-handle',
8786
- template: `
8787
- @if (showFillHandle()) {
8788
- <ko-rect [config]="handleConfig()"></ko-rect>
8789
- }
8790
- `,
8791
- imports: [KoShape]
8792
- }]
8793
- }] });
8794
-
8795
- class AITableCoverCellEntry {
8796
- constructor() {
8797
- this.config = input.required();
8798
- this.onlyDisplayBorder = input(false);
8799
- this.componentMap = {};
8800
- this.groupConfig = computed(() => {
8801
- return {
8802
- x: this.coverCellConfig()?.x,
8803
- y: this.coverCellConfig()?.y,
8804
- listening: true
8805
- };
8806
- });
8807
- this.coverCellConfig = computed(() => {
8808
- const { aiTable, coordinate, references, readonly, actions } = this.config();
8809
- const coverCell = this.coverCell();
8810
- if (!coverCell) {
8811
- return;
8812
- }
8813
- const { field, recordId, isExpand } = coverCell;
8814
- const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, field._id]);
8815
- const fieldModel = FieldModelMap[field.type];
8816
- const transformValue = fieldModel.transformCellValue(cellValue, { aiTable, field });
8817
- const { rowHeight, columnCount, rowCount } = coordinate;
8818
- const columnIndex = aiTable.context?.visibleColumnsIndexMap().get(field._id) ?? 0;
8819
- const rowIndex = aiTable.context?.visibleRowsIndexMap().get(recordId) ?? 0;
8820
- const x = coordinate.getColumnOffset(columnIndex) + AI_TABLE_OFFSET;
8821
- const columnWidth = coordinate.getColumnWidth(columnIndex);
8822
- const y = coordinate.getRowOffset(rowIndex) + AI_TABLE_OFFSET;
8823
- const { width } = getCellHorizontalPosition({
8824
- columnWidth,
8825
- columnIndex,
8826
- columnCount
8827
- });
8828
- const style = {
8829
- textAlign: DEFAULT_TEXT_ALIGN_LEFT
8830
- };
8831
- const textAlign = style.textAlign;
8832
- const renderX = textAlign === DEFAULT_TEXT_ALIGN_RIGHT
8833
- ? columnWidth - AI_TABLE_CELL_PADDING + AI_TABLE_OFFSET
8834
- : AI_TABLE_CELL_PADDING + AI_TABLE_OFFSET;
8835
- const renderY = 0 - AI_TABLE_OFFSET * 2;
8836
- const result = {
8837
- field,
8838
- recordId,
8839
- aiTable,
8840
- coordinate,
8841
- x,
8842
- y,
8843
- readonly,
8844
- actions,
8845
- isExpand,
8846
- render: {
8847
- aiTable,
8848
- recordId,
8849
- field,
8850
- isActive: isSelectedField(field._id, aiTable),
8851
- x: renderX,
8852
- y: renderY,
8853
- columnWidth: width,
8854
- rowHeight,
8855
- cellValue,
8856
- transformValue,
8857
- style,
8858
- references
8859
- }
8860
- };
8861
- return result;
8862
- });
8863
- this.coverCell = computed(() => getCoverCell(this.config().aiTable));
8864
- }
8865
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCoverCellEntry, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8866
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableCoverCellEntry, isStandalone: true, selector: "ai-table-cover-cell-entry", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, onlyDisplayBorder: { classPropertyName: "onlyDisplayBorder", publicName: "onlyDisplayBorder", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
8867
- @if (coverCell()) {
8868
- <ko-group #rootGroup [config]="groupConfig()">
8869
- <ng-container
8870
- *ngComponentOutlet="
8871
- coverCell()!.renderComponentDefinition;
8872
- inputs: { config: coverCellConfig(), onlyDisplayBorder: onlyDisplayBorder() }
8873
- "
8874
- >
8875
- </ng-container>
8876
- </ko-group>
8877
- }
8878
- `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8879
- }
8880
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCoverCellEntry, decorators: [{
8881
- type: Component,
8882
- args: [{
8883
- selector: 'ai-table-cover-cell-entry',
8884
- template: `
8885
- @if (coverCell()) {
8886
- <ko-group #rootGroup [config]="groupConfig()">
8887
- <ng-container
8888
- *ngComponentOutlet="
8889
- coverCell()!.renderComponentDefinition;
8890
- inputs: { config: coverCellConfig(), onlyDisplayBorder: onlyDisplayBorder() }
8891
- "
8892
- >
8893
- </ng-container>
8894
- </ko-group>
8895
- }
8896
- `,
8897
- imports: [KoContainer, CommonModule],
8898
- changeDetection: ChangeDetectionStrategy.OnPush
8899
- }]
8900
- }] });
9010
+ return groups;
9011
+ };
8901
9012
 
8902
9013
  const createFieldStats = (config) => {
8903
9014
  const { coordinate, columnStartIndex, columnStopIndex, aiTable, actions, y, isHoverStatContainer, readonly } = config;
@@ -8913,7 +9024,7 @@ const createFieldStats = (config) => {
8913
9024
  const field = fields[columnIndex];
8914
9025
  if (field == null)
8915
9026
  continue;
8916
- const x = coordinate.getColumnOffset(columnIndex);
9027
+ const x = coordinate.getColumnOffset(columnIndex) + AI_TABLE_OFFSET;
8917
9028
  const columnWidth = coordinate.getColumnWidth(columnIndex);
8918
9029
  const fieldStat = {
8919
9030
  aiTable,
@@ -8923,7 +9034,7 @@ const createFieldStats = (config) => {
8923
9034
  x,
8924
9035
  y,
8925
9036
  width: columnWidth,
8926
- height: AI_TABLE_FIELD_STAT_INNER_HEIGHT,
9037
+ height: AI_TABLE_FIELD_STAT_CONTAINER_HEIGHT,
8927
9038
  field,
8928
9039
  stroke: columnIndex === 0 ? colors.transparent : undefined,
8929
9040
  isHoverStatContainer: isHoverStatContainer,
@@ -8933,6 +9044,41 @@ const createFieldStats = (config) => {
8933
9044
  }
8934
9045
  return fieldStats;
8935
9046
  };
9047
+ const createGroupFieldStats = (config) => {
9048
+ const { coordinate, columnStartIndex, columnStopIndex, aiTable, actions, y, height, isHoverStatContainer, readonly, groupRow } = config;
9049
+ const colors = Colors;
9050
+ const { columnCount, rowInitSize: fieldHeadHeight } = coordinate;
9051
+ const fields = aiTable.gridData().fields;
9052
+ const fieldStats = [];
9053
+ for (let columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) {
9054
+ if (columnIndex > columnCount - 1)
9055
+ break;
9056
+ if (columnIndex < 0)
9057
+ continue;
9058
+ const field = fields[columnIndex];
9059
+ if (field == null)
9060
+ continue;
9061
+ const x = coordinate.getColumnOffset(columnIndex) + AI_TABLE_OFFSET;
9062
+ const columnWidth = coordinate.getColumnWidth(columnIndex);
9063
+ const fieldStat = {
9064
+ aiTable,
9065
+ coordinate,
9066
+ actions,
9067
+ columnIndex,
9068
+ x,
9069
+ y: y,
9070
+ width: columnWidth,
9071
+ height: height ?? AI_TABLE_FIELD_HEAD_HEIGHT,
9072
+ field,
9073
+ isHoverStatContainer: isHoverStatContainer,
9074
+ readonly,
9075
+ isGroupStat: true,
9076
+ groupRow: groupRow
9077
+ };
9078
+ fieldStats.push(fieldStat);
9079
+ }
9080
+ return fieldStats;
9081
+ };
8936
9082
 
8937
9083
  class AITableStatTypeMenu extends ThyDropdownAbstractMenu {
8938
9084
  constructor() {
@@ -8977,8 +9123,11 @@ class AITableFieldStat {
8977
9123
  y: this.config().y
8978
9124
  };
8979
9125
  });
9126
+ this.isGroupStat = computed(() => {
9127
+ return this.config().isGroupStat;
9128
+ });
8980
9129
  this.bgConfig = computed(() => {
8981
- const { field, width, height, coordinate, readonly, aiTable } = this.config();
9130
+ const { field, width, height, coordinate, readonly, aiTable, isGroupStat, columnIndex } = this.config();
8982
9131
  const rowHeadWidth = aiTable.context.rowHeadWidth();
8983
9132
  const config = {
8984
9133
  coordinate,
@@ -8989,27 +9138,50 @@ class AITableFieldStat {
8989
9138
  fieldId: field._id,
8990
9139
  mouseStyle: 'pointer'
8991
9140
  }),
8992
- width: this.isFirstColumn() ? width + AI_TABLE_OFFSET : width,
9141
+ width: width,
8993
9142
  height: height,
8994
9143
  fill: Colors.white,
8995
9144
  hoverFill: Colors.gray100,
8996
9145
  opacity: 1,
8997
9146
  listening: !readonly
8998
9147
  };
8999
- if (this.renderTexts()) {
9000
- config.borders = [false, true, false, true];
9001
- config.stroke = Colors.gray200;
9002
- config.strokeWidth = AI_TABLE_CELL_LINE_BORDER;
9148
+ if (isGroupStat) {
9149
+ if (columnIndex === 0) {
9150
+ const textsConfig = this.textsConfig();
9151
+ if (textsConfig) {
9152
+ config.x = textsConfig[0].x - AI_TABLE_CELL_PADDING;
9153
+ config.width = config.width - config.x;
9154
+ }
9155
+ else {
9156
+ config.width = this.noneStatWidth();
9157
+ config.x = width - this.noneStatWidth();
9158
+ config.fill = Colors.transparent;
9159
+ }
9160
+ }
9003
9161
  }
9004
- if (this.isFirstColumn()) {
9005
- if (rowHeadWidth === 0) {
9162
+ else {
9163
+ if (this.renderTexts()) {
9164
+ config.borders = [false, true, false, true];
9165
+ config.stroke = Colors.gray200;
9166
+ config.strokeWidth = AI_TABLE_CELL_LINE_BORDER;
9167
+ }
9168
+ else if (this.isLastFrozenColumn()) {
9006
9169
  config.borders = [false, true, false, false];
9170
+ config.stroke = Colors.gray200;
9171
+ config.strokeWidth = AI_TABLE_CELL_LINE_BORDER;
9007
9172
  }
9008
- else {
9009
- config.borders = [false, true, false, true];
9173
+ if (this.isFirstColumn()) {
9174
+ if (rowHeadWidth === 0) {
9175
+ config.borders = [false, true, false, false];
9176
+ }
9177
+ else {
9178
+ config.x = -AI_TABLE_OFFSET;
9179
+ config.width = config.width + AI_TABLE_OFFSET;
9180
+ config.borders = [false, true, false, true];
9181
+ }
9182
+ config.stroke = Colors.gray200;
9183
+ config.strokeWidth = AI_TABLE_CELL_LINE_BORDER;
9010
9184
  }
9011
- config.stroke = Colors.gray200;
9012
- config.strokeWidth = AI_TABLE_CELL_LINE_BORDER;
9013
9185
  }
9014
9186
  return config;
9015
9187
  });
@@ -9017,9 +9189,28 @@ class AITableFieldStat {
9017
9189
  const { field } = this.config();
9018
9190
  return field;
9019
9191
  });
9020
- this.records = computed(() => {
9192
+ this.linearRows = computed(() => {
9021
9193
  const { aiTable } = this.config();
9022
- return aiTable.gridData().records;
9194
+ return aiTable.context?.linearRows();
9195
+ });
9196
+ this.recordsMap = computed(() => {
9197
+ const { aiTable } = this.config();
9198
+ return aiTable.recordsMap();
9199
+ });
9200
+ this.groupRow = computed(() => this.config().groupRow);
9201
+ this.gridData = computed(() => this.config().aiTable.gridData());
9202
+ this.records = computed(() => {
9203
+ let records = [];
9204
+ const groupRow = this.groupRow();
9205
+ if (this.isGroupStat()) {
9206
+ if (groupRow.range?.length === 2) {
9207
+ records = this.gridData().records.slice(groupRow.range[0], groupRow.range[1] + 1);
9208
+ }
9209
+ }
9210
+ else {
9211
+ records = this.gridData().records;
9212
+ }
9213
+ return records;
9023
9214
  });
9024
9215
  this.aiFieldConfig = computed(() => {
9025
9216
  const { aiTable } = this.config();
@@ -9052,6 +9243,15 @@ class AITableFieldStat {
9052
9243
  const { width } = this.config();
9053
9244
  return width;
9054
9245
  });
9246
+ this.noneStatWidth = computed(() => {
9247
+ const noneStatString = getI18nTextByKey(this.aiTable(), AITableGridI18nKey.stat);
9248
+ const { text, textWidth } = drawer.textEllipsis({
9249
+ text: noneStatString,
9250
+ fontSize: DEFAULT_FONT_SIZE,
9251
+ fontWeight: DEFAULT_FONT_WEIGHT
9252
+ });
9253
+ return textWidth + AI_TABLE_ACTION_COMMON_SIZE + AI_TABLE_OFFSET;
9254
+ });
9055
9255
  this.renderTexts = computed(() => {
9056
9256
  const width = this.containerBoxWidth();
9057
9257
  const field = this.field();
@@ -9061,7 +9261,7 @@ class AITableFieldStat {
9061
9261
  let resultString = null;
9062
9262
  let formatString = null;
9063
9263
  let statValue = '';
9064
- if (this.isFirstColumn() && selectedInfo.isSelected) {
9264
+ if (this.isFirstColumn() && selectedInfo.isSelected && !this.isGroupStat()) {
9065
9265
  if (selectedInfo.selectedType === 'records') {
9066
9266
  formatString = getI18nTextByKey(this.aiTable(), AITableGridI18nKey.selectedRecordsCount);
9067
9267
  }
@@ -9189,6 +9389,10 @@ class AITableFieldStat {
9189
9389
  const { columnIndex } = this.config();
9190
9390
  return columnIndex === 0;
9191
9391
  });
9392
+ this.isLastFrozenColumn = computed(() => {
9393
+ const { columnIndex, coordinate } = this.config();
9394
+ return columnIndex === coordinate.frozenColumnCount - 1;
9395
+ });
9192
9396
  this.iconConfig = computed(() => {
9193
9397
  const { field, width, height } = this.config();
9194
9398
  const commonIconOffsetY = (height - AI_TABLE_ACTION_COMMON_SIZE) / 2;
@@ -9305,6 +9509,327 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
9305
9509
  }]
9306
9510
  }] });
9307
9511
 
9512
+ class AITableGroups {
9513
+ constructor() {
9514
+ this.config = input.required();
9515
+ this.frozenColumnCount = computed(() => {
9516
+ const { coordinate } = this.config();
9517
+ return coordinate.frozenColumnCount ?? 0;
9518
+ });
9519
+ this.columnStartIndex = computed(() => {
9520
+ const { columnStartIndex } = this.config();
9521
+ return Math.max(columnStartIndex, this.frozenColumnCount());
9522
+ });
9523
+ this.groups = computed(() => {
9524
+ return createGroupCells({
9525
+ ...this.config(),
9526
+ columnStartIndex: this.columnStartIndex()
9527
+ });
9528
+ });
9529
+ this.groupCells = computed(() => {
9530
+ const groups = this.groups();
9531
+ const groupCells = [];
9532
+ groups.forEach((group) => {
9533
+ const { row, x = 0, y = 0 } = group;
9534
+ const groupStats = createGroupFieldStats({
9535
+ ...this.config(),
9536
+ groupRow: row,
9537
+ x,
9538
+ y,
9539
+ columnStartIndex: this.columnStartIndex()
9540
+ });
9541
+ groupStats.forEach((groupStat) => {
9542
+ groupCells.push({ groupStat: groupStat });
9543
+ });
9544
+ });
9545
+ return groupCells;
9546
+ });
9547
+ }
9548
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableGroups, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9549
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableGroups, isStandalone: true, selector: "ai-table-groups", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
9550
+ @for (groupCell of groupCells(); track $index) {
9551
+ <ai-table-field-stat [config]="groupCell.groupStat!"></ai-table-field-stat>
9552
+ }
9553
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AITableFieldStat, selector: "ai-table-field-stat", inputs: ["config"], outputs: ["hover"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9554
+ }
9555
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableGroups, decorators: [{
9556
+ type: Component,
9557
+ args: [{
9558
+ selector: 'ai-table-groups',
9559
+ template: `
9560
+ @for (groupCell of groupCells(); track $index) {
9561
+ <ai-table-field-stat [config]="groupCell.groupStat!"></ai-table-field-stat>
9562
+ }
9563
+ `,
9564
+ imports: [CommonModule, AITableFieldStat],
9565
+ changeDetection: ChangeDetectionStrategy.OnPush
9566
+ }]
9567
+ }] });
9568
+
9569
+ class AITableFrozenGroups {
9570
+ constructor() {
9571
+ this.config = input.required();
9572
+ this.frozenColumnCount = computed(() => {
9573
+ const { coordinate } = this.config();
9574
+ return coordinate.frozenColumnCount ?? 0;
9575
+ });
9576
+ this.columnStopIndex = computed(() => {
9577
+ return this.frozenColumnCount() - 1;
9578
+ });
9579
+ this.groups = computed(() => {
9580
+ return createGroupCells({
9581
+ ...this.config(),
9582
+ columnStartIndex: 0,
9583
+ columnStopIndex: this.columnStopIndex()
9584
+ });
9585
+ });
9586
+ this.groupCells = computed(() => {
9587
+ const groups = this.groups();
9588
+ const groupCells = [];
9589
+ groups.forEach((group) => {
9590
+ const { row, x = 0, y = 0, height, readonly } = group;
9591
+ const { isCollapsed, fieldId, groupId } = row;
9592
+ const collapsedIcon = {
9593
+ name: generateTargetName({
9594
+ targetName: AI_TABLE_ROW_GROUP_COLLAPSE_BUTTON,
9595
+ fieldId: fieldId,
9596
+ source: groupId,
9597
+ mouseStyle: readonly ? 'default' : 'pointer'
9598
+ }),
9599
+ x,
9600
+ y: y + (height - AI_TABLE_ICON_COMMON_SIZE) / 2,
9601
+ data: isCollapsed ? AngleRightPath : AngleDownPath
9602
+ };
9603
+ const groupStats = createGroupFieldStats({
9604
+ ...this.config(),
9605
+ groupRow: row,
9606
+ x,
9607
+ y,
9608
+ columnStartIndex: 0,
9609
+ columnStopIndex: this.columnStopIndex()
9610
+ });
9611
+ groupStats.forEach((groupStat) => {
9612
+ const groupCell = {
9613
+ collapsedIcon: undefined,
9614
+ groupStat: undefined
9615
+ };
9616
+ if (groupStat.columnIndex === 0) {
9617
+ groupCell.collapsedIcon = collapsedIcon;
9618
+ }
9619
+ groupCell.groupStat = groupStat;
9620
+ groupCells.push(groupCell);
9621
+ });
9622
+ });
9623
+ return groupCells;
9624
+ });
9625
+ }
9626
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableFrozenGroups, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9627
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableFrozenGroups, isStandalone: true, selector: "ai-table-frozen-groups", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
9628
+ @for (groupCell of groupCells(); track $index) {
9629
+ @if (groupCell.collapsedIcon) {
9630
+ <ai-table-icon [config]="groupCell.collapsedIcon"></ai-table-icon>
9631
+ }
9632
+ <ai-table-field-stat [config]="groupCell.groupStat!"></ai-table-field-stat>
9633
+ }
9634
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AITableIcon, selector: "ai-table-icon", inputs: ["config"], outputs: ["koClick"] }, { kind: "component", type: AITableFieldStat, selector: "ai-table-field-stat", inputs: ["config"], outputs: ["hover"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9635
+ }
9636
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableFrozenGroups, decorators: [{
9637
+ type: Component,
9638
+ args: [{
9639
+ selector: 'ai-table-frozen-groups',
9640
+ template: `
9641
+ @for (groupCell of groupCells(); track $index) {
9642
+ @if (groupCell.collapsedIcon) {
9643
+ <ai-table-icon [config]="groupCell.collapsedIcon"></ai-table-icon>
9644
+ }
9645
+ <ai-table-field-stat [config]="groupCell.groupStat!"></ai-table-field-stat>
9646
+ }
9647
+ `,
9648
+ imports: [CommonModule, AITableIcon, AITableFieldStat],
9649
+ changeDetection: ChangeDetectionStrategy.OnPush
9650
+ }]
9651
+ }] });
9652
+
9653
+ class AITableFillHandle {
9654
+ constructor() {
9655
+ this.config = input.required();
9656
+ this.showFillHandle = computed(() => {
9657
+ const { aiTable, readonly } = this.config();
9658
+ const selection = aiTable.selection();
9659
+ const hasSelectedCells = selection.selectedCells.size > 0;
9660
+ const isEditingCell = !!aiTable.editingCell()?.path;
9661
+ return hasSelectedCells && !readonly && !isEditingCell;
9662
+ });
9663
+ this.handleConfig = computed(() => {
9664
+ const { aiTable, coordinate } = this.config();
9665
+ const selectedCells = Array.from(aiTable.selection().selectedCells);
9666
+ const lastCell = selectedCells[selectedCells.length - 1];
9667
+ const [recordId, fieldId] = lastCell.split(':');
9668
+ const columnIndex = aiTable.context.visibleColumnsIndexMap().get(fieldId);
9669
+ const columnOffset = coordinate.getColumnOffset(columnIndex);
9670
+ const columnWidth = coordinate.getColumnWidth(columnIndex);
9671
+ const rowIndex = aiTable.context.visibleRowsIndexMap().get(recordId);
9672
+ const rowOffset = coordinate.getRowOffset(rowIndex);
9673
+ const width = 6;
9674
+ const height = 6;
9675
+ const [expandRecordId, expandFieldId] = aiTable.expendCell()?.path || [null, null];
9676
+ const cellHeight = expandRecordId === recordId && expandFieldId === fieldId && aiTable.expendCell()?.height
9677
+ ? aiTable.expendCell()?.height
9678
+ ? aiTable.expendCell().height + AI_TABLE_CELL_LINE_BORDER
9679
+ : AI_TABLE_ROW_HEIGHT
9680
+ : AI_TABLE_ROW_HEIGHT;
9681
+ return {
9682
+ x: columnOffset + columnWidth - width / 2 + AI_TABLE_OFFSET,
9683
+ y: rowOffset + cellHeight - height + AI_TABLE_CELL_BORDER + AI_TABLE_OFFSET,
9684
+ width,
9685
+ height,
9686
+ fill: Colors.primary,
9687
+ stroke: Colors.white,
9688
+ strokeWidth: 2,
9689
+ zIndex: 20,
9690
+ name: generateTargetName({
9691
+ targetName: AI_TABLE_FILL_HANDLE,
9692
+ fieldId,
9693
+ recordId
9694
+ })
9695
+ };
9696
+ });
9697
+ }
9698
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableFillHandle, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9699
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableFillHandle, isStandalone: true, selector: "ai-table-fill-handle", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
9700
+ @if (showFillHandle()) {
9701
+ <ko-rect [config]="handleConfig()"></ko-rect>
9702
+ }
9703
+ `, isInline: true, dependencies: [{ kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }] }); }
9704
+ }
9705
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableFillHandle, decorators: [{
9706
+ type: Component,
9707
+ args: [{
9708
+ selector: 'ai-table-fill-handle',
9709
+ template: `
9710
+ @if (showFillHandle()) {
9711
+ <ko-rect [config]="handleConfig()"></ko-rect>
9712
+ }
9713
+ `,
9714
+ imports: [KoShape]
9715
+ }]
9716
+ }] });
9717
+
9718
+ class AITableCoverCellEntry {
9719
+ constructor() {
9720
+ this.config = input.required();
9721
+ this.onlyDisplayBorder = input(false);
9722
+ this.componentMap = {};
9723
+ this.groupConfig = computed(() => {
9724
+ return {
9725
+ x: this.coverCellConfig()?.x,
9726
+ y: this.coverCellConfig()?.y,
9727
+ listening: true
9728
+ };
9729
+ });
9730
+ this.coverCellConfig = computed(() => {
9731
+ const { aiTable, coordinate, references, readonly, actions } = this.config();
9732
+ const coverCell = this.coverCell();
9733
+ if (!coverCell) {
9734
+ return;
9735
+ }
9736
+ const { field, recordId, isExpand } = coverCell;
9737
+ const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, field._id]);
9738
+ const fieldModel = FieldModelMap[field.type];
9739
+ const transformValue = fieldModel.transformCellValue(cellValue, { aiTable, field });
9740
+ const { rowHeight, columnCount, rowCount } = coordinate;
9741
+ const columnIndex = aiTable.context?.visibleColumnsIndexMap().get(field._id) ?? 0;
9742
+ const rowIndex = aiTable.context?.visibleRowsIndexMap().get(recordId) ?? 0;
9743
+ const row = aiTable.context?.linearRows()[rowIndex];
9744
+ const depth = row?.depth ?? 0;
9745
+ const x = coordinate.getColumnOffset(columnIndex) + AI_TABLE_OFFSET;
9746
+ const columnWidth = coordinate.getColumnWidth(columnIndex);
9747
+ const y = coordinate.getRowOffset(rowIndex) + AI_TABLE_OFFSET;
9748
+ const isGroupAndFirstColumn = depth > 0 && columnIndex === 0;
9749
+ const { width, offset } = getCellHorizontalPosition({
9750
+ columnIndex,
9751
+ columnWidth: isGroupAndFirstColumn ? columnWidth - AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE : columnWidth,
9752
+ columnCount,
9753
+ depth
9754
+ });
9755
+ let realX = x + offset;
9756
+ if (isGroupAndFirstColumn) {
9757
+ realX += AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE;
9758
+ }
9759
+ const style = {
9760
+ textAlign: DEFAULT_TEXT_ALIGN_LEFT
9761
+ };
9762
+ const textAlign = style.textAlign;
9763
+ const renderX = textAlign === DEFAULT_TEXT_ALIGN_RIGHT
9764
+ ? columnWidth - AI_TABLE_CELL_PADDING + AI_TABLE_OFFSET
9765
+ : AI_TABLE_CELL_PADDING + AI_TABLE_OFFSET;
9766
+ const renderY = 0 - AI_TABLE_OFFSET * 2;
9767
+ const result = {
9768
+ field,
9769
+ recordId,
9770
+ aiTable,
9771
+ coordinate,
9772
+ x: realX,
9773
+ y,
9774
+ readonly,
9775
+ actions,
9776
+ isExpand,
9777
+ render: {
9778
+ aiTable,
9779
+ recordId,
9780
+ field,
9781
+ isActive: isSelectedField(field._id, aiTable),
9782
+ x: renderX,
9783
+ y: renderY,
9784
+ columnWidth: width,
9785
+ rowHeight,
9786
+ cellValue,
9787
+ transformValue,
9788
+ style,
9789
+ references
9790
+ }
9791
+ };
9792
+ return result;
9793
+ });
9794
+ this.coverCell = computed(() => getCoverCell(this.config().aiTable));
9795
+ }
9796
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCoverCellEntry, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9797
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableCoverCellEntry, isStandalone: true, selector: "ai-table-cover-cell-entry", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, onlyDisplayBorder: { classPropertyName: "onlyDisplayBorder", publicName: "onlyDisplayBorder", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
9798
+ @if (coverCell()) {
9799
+ <ko-group #rootGroup [config]="groupConfig()">
9800
+ <ng-container
9801
+ *ngComponentOutlet="
9802
+ coverCell()!.renderComponentDefinition;
9803
+ inputs: { config: coverCellConfig(), onlyDisplayBorder: onlyDisplayBorder() }
9804
+ "
9805
+ >
9806
+ </ng-container>
9807
+ </ko-group>
9808
+ }
9809
+ `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9810
+ }
9811
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCoverCellEntry, decorators: [{
9812
+ type: Component,
9813
+ args: [{
9814
+ selector: 'ai-table-cover-cell-entry',
9815
+ template: `
9816
+ @if (coverCell()) {
9817
+ <ko-group #rootGroup [config]="groupConfig()">
9818
+ <ng-container
9819
+ *ngComponentOutlet="
9820
+ coverCell()!.renderComponentDefinition;
9821
+ inputs: { config: coverCellConfig(), onlyDisplayBorder: onlyDisplayBorder() }
9822
+ "
9823
+ >
9824
+ </ng-container>
9825
+ </ko-group>
9826
+ }
9827
+ `,
9828
+ imports: [KoContainer, CommonModule],
9829
+ changeDetection: ChangeDetectionStrategy.OnPush
9830
+ }]
9831
+ }] });
9832
+
9308
9833
  class AITableFieldStats {
9309
9834
  constructor() {
9310
9835
  this.config = input.required();
@@ -9426,6 +9951,14 @@ class AITableRenderer {
9426
9951
  this.scrollTotalWidth = computed(() => {
9427
9952
  return this.coordinate().totalWidth + AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
9428
9953
  });
9954
+ this.frozenCommonGroupConfig = computed(() => {
9955
+ return {
9956
+ clipX: 0,
9957
+ clipY: AI_TABLE_FIELD_HEAD_HEIGHT,
9958
+ clipWidth: this.frozenAreaWidth() + AI_TABLE_SHADOW_DEFAULT_WIDTH,
9959
+ clipHeight: this.gridContainerHeight()
9960
+ };
9961
+ });
9429
9962
  this.commonGroupConfig = computed(() => {
9430
9963
  return {
9431
9964
  clipX: this.frozenAreaWidth() + 1,
@@ -9525,11 +10058,32 @@ class AITableRenderer {
9525
10058
  ...this.columnHeadFieldConfig(),
9526
10059
  width: this.cellGroupClipWidth(),
9527
10060
  x: this.frozenAreaWidth(),
9528
- y: AI_TABLE_OFFSET,
10061
+ y: 0,
9529
10062
  height: AI_TABLE_FIELD_STAT_CONTAINER_HEIGHT,
9530
10063
  isHoverStatContainer: this.isHoverStatContainer()
9531
10064
  };
9532
10065
  });
10066
+ this.xIsScroll = computed(() => {
10067
+ return this.scrollState().scrollLeft > 0;
10068
+ });
10069
+ this.statShadowConfig = computed(() => {
10070
+ return {
10071
+ width: 8,
10072
+ x: this.frozenAreaWidth() + 1,
10073
+ y: AI_TABLE_OFFSET,
10074
+ height: AI_TABLE_FIELD_STAT_CONTAINER_HEIGHT,
10075
+ visible: this.xIsScroll()
10076
+ };
10077
+ });
10078
+ this.fieldHeadShadowConfig = computed(() => {
10079
+ return {
10080
+ width: AI_TABLE_SHADOW_DEFAULT_WIDTH,
10081
+ x: this.frozenAreaWidth() + 1,
10082
+ y: AI_TABLE_OFFSET,
10083
+ height: AI_TABLE_FIELD_HEAD_HEIGHT,
10084
+ visible: this.xIsScroll()
10085
+ };
10086
+ });
9533
10087
  this.columnFieldStatsBgConfig = computed(() => {
9534
10088
  return {
9535
10089
  x: 0,
@@ -9550,7 +10104,7 @@ class AITableRenderer {
9550
10104
  ...this.columnHeadFieldConfig(),
9551
10105
  width: this.frozenAreaWidth(),
9552
10106
  x: 0,
9553
- y: AI_TABLE_OFFSET,
10107
+ y: 0,
9554
10108
  columnStartIndex: 0,
9555
10109
  columnStopIndex: this.coordinate().frozenColumnCount - 1,
9556
10110
  height: AI_TABLE_FIELD_STAT_CONTAINER_HEIGHT,
@@ -9599,13 +10153,16 @@ class AITableRenderer {
9599
10153
  const { aiTable } = this.config();
9600
10154
  const expandCellPath = aiTable.expendCell()?.path;
9601
10155
  if (expandCellPath) {
9602
- const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, expandCellPath);
9603
- const isFrozenColumn = columnIndex < aiTable.context.frozenColumnCount();
9604
- if (isFrozenColumn) {
9605
- frozenExpandCellBorder = true;
9606
- }
9607
- else {
9608
- expandCellBorder = true;
10156
+ const cellIndex = AITable.getCellIndex(aiTable, expandCellPath);
10157
+ if (cellIndex) {
10158
+ const { columnIndex } = cellIndex;
10159
+ const isFrozenColumn = columnIndex < aiTable.context.frozenColumnCount();
10160
+ if (isFrozenColumn) {
10161
+ frozenExpandCellBorder = true;
10162
+ }
10163
+ else {
10164
+ expandCellBorder = true;
10165
+ }
9609
10166
  }
9610
10167
  }
9611
10168
  return {
@@ -9642,7 +10199,7 @@ class AITableRenderer {
9642
10199
  this.isHoverStatContainer.set(isHover);
9643
10200
  }
9644
10201
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9645
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableRenderer, isStandalone: true, selector: "ai-table-renderer", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { koMousemove: "koMousemove", koMousedown: "koMousedown", koMouseup: "koMouseup", koContextmenu: "koContextmenu", koWheel: "koWheel", koClick: "koClick", koDblclick: "koDblclick", koMouseleave: "koMouseleave", onScrollPosition: "onScrollPosition" }, ngImport: i0, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n (koMouseleave)=\"stageMouseleave($event)\"\n (koWheel)=\"stageWheel($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n @if (!hiddenIndexColumn()) {\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n }\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnFrozenHeadFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group #commonOffsetGroup [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\"></ai-table-cover-cell-entry>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-field-shadow [config]=\"config()\"></ai-table-frozen-field-shadow>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n @if (showExpandCellBorder().expandCellBorder) {\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\" [onlyDisplayBorder]=\"true\"></ai-table-cover-cell-entry>\n }\n @if (!isLastSelectedCellInFrozenColumn()) {\n <ai-table-fill-handle [config]=\"fillHandleConfig()\"></ai-table-fill-handle>\n }\n </ko-group>\n </ko-group>\n <ko-group [config]=\"frozenCoverAttachGroupConfig()\">\n <ko-group #frozenCoverAttachOffsetGroup [config]=\"offsetYConfig()\">\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\"></ai-table-cover-cell-entry>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n @if (showExpandCellBorder().frozenExpandCellBorder) {\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\" [onlyDisplayBorder]=\"true\"></ai-table-cover-cell-entry>\n }\n @if (isLastSelectedCellInFrozenColumn()) {\n <ai-table-fill-handle [config]=\"fillHandleConfig()\"></ai-table-fill-handle>\n }\n </ko-group>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"statGroupConfig()\">\n <ai-table-background [config]=\"columnFieldStatsBgConfig()\"></ai-table-background>\n <ko-group>\n <ai-table-column-stats\n [config]=\"columnFrozenFieldStatsConfig()\"\n (hover)=\"onStatContainerHover($event)\"\n ></ai-table-column-stats>\n </ko-group>\n <ko-group [config]=\"statCommonGroupConfig()\">\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-stats\n [config]=\"columnFieldStatsConfig()\"\n (hover)=\"onStatContainerHover($event)\"\n ></ai-table-column-stats>\n </ko-group>\n </ko-group>\n <ko-group>\n <ai-table-frozen-field-shadow [config]=\"columnFieldStatsConfig()\" position=\"fieldStats\"></ai-table-frozen-field-shadow>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n", dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoStage, selector: "ko-stage", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableColumnHeads, selector: "ai-table-column-heads", inputs: ["config"] }, { kind: "component", type: AITableFrozenColumnHeads, selector: "ai-table-frozen-column-heads", inputs: ["config"] }, { kind: "component", type: AITableCells, selector: "ai-table-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenCells, selector: "ai-table-frozen-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenPlaceholderCells, selector: "ai-table-frozen-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITableCoverCellEntry, selector: "ai-table-cover-cell-entry", inputs: ["config", "onlyDisplayBorder"] }, { kind: "component", type: AITablePlaceholderCells, selector: "ai-table-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITableAddField, selector: "ai-table-add-field", inputs: ["config"] }, { kind: "component", type: AITableHoverRowHeads, selector: "ai-table-hover-row-heads", inputs: ["config"] }, { kind: "component", type: AITableOtherRows, selector: "ai-table-other-rows", inputs: ["config"] }, { kind: "component", type: AITableFillHandle, selector: "ai-table-fill-handle", inputs: ["config"] }, { kind: "component", type: AITableFieldStats, selector: "ai-table-column-stats", inputs: ["config"], outputs: ["hover"] }, { kind: "component", type: AITableBackground, selector: "ai-table-background", inputs: ["config", "isActive", "isHover"], outputs: ["koClick", "hover", "koMouseenter", "koMouseleave", "isHoverChange"] }, { kind: "component", type: AITableFrozenFieldShadow, selector: "ai-table-frozen-field-shadow", inputs: ["config", "position"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
10202
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableRenderer, isStandalone: true, selector: "ai-table-renderer", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { koMousemove: "koMousemove", koMousedown: "koMousedown", koMouseup: "koMouseup", koContextmenu: "koContextmenu", koWheel: "koWheel", koClick: "koClick", koDblclick: "koDblclick", koMouseleave: "koMouseleave", onScrollPosition: "onScrollPosition" }, ngImport: i0, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n (koMouseleave)=\"stageMouseleave($event)\"\n (koWheel)=\"stageWheel($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <!-- \u53F3\u4FA7\u975E\u56FA\u5B9A\u5217\u7684\u533A\u57DF -->\n <ko-group [config]=\"commonGroupConfig()\">\n <!-- \u53F3\u4FA7x,y\u6EDA\u52A8\u533A\u57DF\u7684 cell -->\n <ko-group #commonOffsetGroup [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\"></ai-table-cover-cell-entry>\n <ai-table-groups [config]=\"cellsConfig()\"></ai-table-groups>\n </ko-group>\n\n <!-- \u53F3\u4FA7\u8868\u5934head \u548C \u65B0\u589E\u5217 + \u533A\u57DF -->\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <!-- \u5DE6\u4FA7\u56FA\u5B9A\u5217 y\u6EDA\u52A8\u533A\u57DF\u7684cell -->\n <ko-group [config]=\"frozenCommonGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n @if (!hiddenIndexColumn()) {\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n }\n <ai-table-frozen-groups [config]=\"cellsConfig()\"></ai-table-frozen-groups>\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n </ko-group>\n\n <!-- \u5DE6\u4FA7\u56FA\u5B9A\u5217 \u8868\u5934 + \u8868\u5934\u53F3\u4FA7\u5206\u5272\u9634\u5F71 -->\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnFrozenHeadFieldConfig()\"></ai-table-frozen-column-heads>\n <ai-table-shadow [config]=\"fieldHeadShadowConfig()\"></ai-table-shadow>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n @if (showExpandCellBorder().expandCellBorder) {\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\" [onlyDisplayBorder]=\"true\"></ai-table-cover-cell-entry>\n }\n @if (!isLastSelectedCellInFrozenColumn()) {\n <ai-table-fill-handle [config]=\"fillHandleConfig()\"></ai-table-fill-handle>\n }\n </ko-group>\n </ko-group>\n <ko-group [config]=\"frozenCoverAttachGroupConfig()\">\n <ko-group #frozenCoverAttachOffsetGroup [config]=\"offsetYConfig()\">\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\"></ai-table-cover-cell-entry>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n @if (showExpandCellBorder().frozenExpandCellBorder) {\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\" [onlyDisplayBorder]=\"true\"></ai-table-cover-cell-entry>\n }\n @if (isLastSelectedCellInFrozenColumn()) {\n <ai-table-fill-handle [config]=\"fillHandleConfig()\"></ai-table-fill-handle>\n }\n </ko-group>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"statGroupConfig()\">\n <ai-table-background [config]=\"columnFieldStatsBgConfig()\"></ai-table-background>\n <ko-group>\n <ai-table-column-stats\n [config]=\"columnFrozenFieldStatsConfig()\"\n (hover)=\"onStatContainerHover($event)\"\n ></ai-table-column-stats>\n </ko-group>\n <ko-group [config]=\"statCommonGroupConfig()\">\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-stats\n [config]=\"columnFieldStatsConfig()\"\n (hover)=\"onStatContainerHover($event)\"\n ></ai-table-column-stats>\n </ko-group>\n </ko-group>\n <ko-group>\n <ai-table-shadow [config]=\"statShadowConfig()\"></ai-table-shadow>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n", dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoStage, selector: "ko-stage", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableColumnHeads, selector: "ai-table-column-heads", inputs: ["config"] }, { kind: "component", type: AITableFrozenColumnHeads, selector: "ai-table-frozen-column-heads", inputs: ["config"] }, { kind: "component", type: AITableCells, selector: "ai-table-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenCells, selector: "ai-table-frozen-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenPlaceholderCells, selector: "ai-table-frozen-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITableCoverCellEntry, selector: "ai-table-cover-cell-entry", inputs: ["config", "onlyDisplayBorder"] }, { kind: "component", type: AITablePlaceholderCells, selector: "ai-table-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITableAddField, selector: "ai-table-add-field", inputs: ["config"] }, { kind: "component", type: AITableHoverRowHeads, selector: "ai-table-hover-row-heads", inputs: ["config"] }, { kind: "component", type: AITableOtherRows, selector: "ai-table-other-rows", inputs: ["config"] }, { kind: "component", type: AITableFillHandle, selector: "ai-table-fill-handle", inputs: ["config"] }, { kind: "component", type: AITableFieldStats, selector: "ai-table-column-stats", inputs: ["config"], outputs: ["hover"] }, { kind: "component", type: AITableBackground, selector: "ai-table-background", inputs: ["config", "isActive", "isHover"], outputs: ["koClick", "hover", "koMouseenter", "koMouseleave", "isHoverChange"] }, { kind: "component", type: AITableFrozenGroups, selector: "ai-table-frozen-groups", inputs: ["config"] }, { kind: "component", type: AITableGroups, selector: "ai-table-groups", inputs: ["config"] }, { kind: "component", type: AITableShadow, selector: "ai-table-shadow", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9646
10203
  }
9647
10204
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableRenderer, decorators: [{
9648
10205
  type: Component,
@@ -9663,8 +10220,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
9663
10220
  AITableFillHandle,
9664
10221
  AITableFieldStats,
9665
10222
  AITableBackground,
9666
- AITableFrozenFieldShadow
9667
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n (koMouseleave)=\"stageMouseleave($event)\"\n (koWheel)=\"stageWheel($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n @if (!hiddenIndexColumn()) {\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n }\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnFrozenHeadFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group #commonOffsetGroup [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\"></ai-table-cover-cell-entry>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-field-shadow [config]=\"config()\"></ai-table-frozen-field-shadow>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n @if (showExpandCellBorder().expandCellBorder) {\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\" [onlyDisplayBorder]=\"true\"></ai-table-cover-cell-entry>\n }\n @if (!isLastSelectedCellInFrozenColumn()) {\n <ai-table-fill-handle [config]=\"fillHandleConfig()\"></ai-table-fill-handle>\n }\n </ko-group>\n </ko-group>\n <ko-group [config]=\"frozenCoverAttachGroupConfig()\">\n <ko-group #frozenCoverAttachOffsetGroup [config]=\"offsetYConfig()\">\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\"></ai-table-cover-cell-entry>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n @if (showExpandCellBorder().frozenExpandCellBorder) {\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\" [onlyDisplayBorder]=\"true\"></ai-table-cover-cell-entry>\n }\n @if (isLastSelectedCellInFrozenColumn()) {\n <ai-table-fill-handle [config]=\"fillHandleConfig()\"></ai-table-fill-handle>\n }\n </ko-group>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"statGroupConfig()\">\n <ai-table-background [config]=\"columnFieldStatsBgConfig()\"></ai-table-background>\n <ko-group>\n <ai-table-column-stats\n [config]=\"columnFrozenFieldStatsConfig()\"\n (hover)=\"onStatContainerHover($event)\"\n ></ai-table-column-stats>\n </ko-group>\n <ko-group [config]=\"statCommonGroupConfig()\">\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-stats\n [config]=\"columnFieldStatsConfig()\"\n (hover)=\"onStatContainerHover($event)\"\n ></ai-table-column-stats>\n </ko-group>\n </ko-group>\n <ko-group>\n <ai-table-frozen-field-shadow [config]=\"columnFieldStatsConfig()\" position=\"fieldStats\"></ai-table-frozen-field-shadow>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n" }]
10223
+ AITableFrozenGroups,
10224
+ AITableGroups,
10225
+ AITableShadow,
10226
+ AITableFrozenGroups
10227
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n (koMouseleave)=\"stageMouseleave($event)\"\n (koWheel)=\"stageWheel($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <!-- \u53F3\u4FA7\u975E\u56FA\u5B9A\u5217\u7684\u533A\u57DF -->\n <ko-group [config]=\"commonGroupConfig()\">\n <!-- \u53F3\u4FA7x,y\u6EDA\u52A8\u533A\u57DF\u7684 cell -->\n <ko-group #commonOffsetGroup [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\"></ai-table-cover-cell-entry>\n <ai-table-groups [config]=\"cellsConfig()\"></ai-table-groups>\n </ko-group>\n\n <!-- \u53F3\u4FA7\u8868\u5934head \u548C \u65B0\u589E\u5217 + \u533A\u57DF -->\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <!-- \u5DE6\u4FA7\u56FA\u5B9A\u5217 y\u6EDA\u52A8\u533A\u57DF\u7684cell -->\n <ko-group [config]=\"frozenCommonGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n @if (!hiddenIndexColumn()) {\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n }\n <ai-table-frozen-groups [config]=\"cellsConfig()\"></ai-table-frozen-groups>\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n </ko-group>\n\n <!-- \u5DE6\u4FA7\u56FA\u5B9A\u5217 \u8868\u5934 + \u8868\u5934\u53F3\u4FA7\u5206\u5272\u9634\u5F71 -->\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnFrozenHeadFieldConfig()\"></ai-table-frozen-column-heads>\n <ai-table-shadow [config]=\"fieldHeadShadowConfig()\"></ai-table-shadow>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n @if (showExpandCellBorder().expandCellBorder) {\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\" [onlyDisplayBorder]=\"true\"></ai-table-cover-cell-entry>\n }\n @if (!isLastSelectedCellInFrozenColumn()) {\n <ai-table-fill-handle [config]=\"fillHandleConfig()\"></ai-table-fill-handle>\n }\n </ko-group>\n </ko-group>\n <ko-group [config]=\"frozenCoverAttachGroupConfig()\">\n <ko-group #frozenCoverAttachOffsetGroup [config]=\"offsetYConfig()\">\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\"></ai-table-cover-cell-entry>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n @if (showExpandCellBorder().frozenExpandCellBorder) {\n <ai-table-cover-cell-entry [config]=\"cellsConfig()\" [onlyDisplayBorder]=\"true\"></ai-table-cover-cell-entry>\n }\n @if (isLastSelectedCellInFrozenColumn()) {\n <ai-table-fill-handle [config]=\"fillHandleConfig()\"></ai-table-fill-handle>\n }\n </ko-group>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"statGroupConfig()\">\n <ai-table-background [config]=\"columnFieldStatsBgConfig()\"></ai-table-background>\n <ko-group>\n <ai-table-column-stats\n [config]=\"columnFrozenFieldStatsConfig()\"\n (hover)=\"onStatContainerHover($event)\"\n ></ai-table-column-stats>\n </ko-group>\n <ko-group [config]=\"statCommonGroupConfig()\">\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-stats\n [config]=\"columnFieldStatsConfig()\"\n (hover)=\"onStatContainerHover($event)\"\n ></ai-table-column-stats>\n </ko-group>\n </ko-group>\n <ko-group>\n <ai-table-shadow [config]=\"statShadowConfig()\"></ai-table-shadow>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n" }]
9668
10228
  }] });
9669
10229
 
9670
10230
  class AITableCellRate extends CoverCellBase {
@@ -10575,12 +11135,15 @@ function performFill(aiTable, sourceCells, mouseUpRecordId, actions) {
10575
11135
  targetStartRowIndex = selectedFirstRowIndex;
10576
11136
  targetEndRowIndex = sourceStartRowIndex - 1;
10577
11137
  }
10578
- const sourceRowCount = sourceEndRowIndex - sourceStartRowIndex + 1;
10579
11138
  const sourceRows = [];
10580
11139
  const linearRows = aiTable.context.linearRows();
10581
11140
  for (let i = sourceStartRowIndex; i <= sourceEndRowIndex; i++) {
10582
- sourceRows.push(linearRows[i]._id);
11141
+ const row = linearRows[i];
11142
+ if (row.type === AITableRowType.record) {
11143
+ sourceRows.push(row._id);
11144
+ }
10583
11145
  }
11146
+ const sourceRowCount = sourceRows.length;
10584
11147
  const updateData = [];
10585
11148
  const fields = AITable.getVisibleFields(aiTable);
10586
11149
  const visibleColumnsIndexMap = aiTable.context.visibleColumnsIndexMap();
@@ -10593,17 +11156,44 @@ function performFill(aiTable, sourceCells, mouseUpRecordId, actions) {
10593
11156
  if (isSystemField(field)) {
10594
11157
  continue;
10595
11158
  }
10596
- for (let rowIndex = targetStartRowIndex; rowIndex <= targetEndRowIndex; rowIndex++) {
10597
- const targetRecordId = linearRows[rowIndex]._id;
10598
- const relativeRowIndex = direction === 'downward' ? rowIndex - targetStartRowIndex : targetEndRowIndex - rowIndex;
10599
- const mod = relativeRowIndex % sourceRowCount;
10600
- const sourceRowIndex = direction === 'downward' ? mod : sourceRowCount - 1 - mod;
10601
- const sourceRecordId = sourceRows[sourceRowIndex];
10602
- const sourceValue = recordsMap[sourceRecordId]?.values[fieldId];
10603
- updateData.push({
10604
- path: [targetRecordId, fieldId],
10605
- value: sourceValue
10606
- });
11159
+ if (direction === 'downward') {
11160
+ let sourceRowIndexPointer = 0;
11161
+ for (let rowIndex = targetStartRowIndex; rowIndex <= targetEndRowIndex; rowIndex++) {
11162
+ const row = linearRows[rowIndex];
11163
+ if (row.type === AITableRowType.record) {
11164
+ const targetRecordId = linearRows[rowIndex]._id;
11165
+ const mod = sourceRowIndexPointer % sourceRowCount;
11166
+ const sourceRecordId = sourceRows[mod];
11167
+ const sourceValue = recordsMap[sourceRecordId]?.values[fieldId];
11168
+ updateData.push({
11169
+ path: [targetRecordId, fieldId],
11170
+ value: sourceValue
11171
+ });
11172
+ sourceRowIndexPointer++;
11173
+ }
11174
+ }
11175
+ }
11176
+ else {
11177
+ let sourceRowIndexPointer = sourceRowCount - 1;
11178
+ for (let rowIndex = targetEndRowIndex; rowIndex >= targetStartRowIndex; rowIndex--) {
11179
+ const row = linearRows[rowIndex];
11180
+ if (row.type === AITableRowType.record) {
11181
+ const targetRecordId = linearRows[rowIndex]._id;
11182
+ const mod = sourceRowIndexPointer % sourceRowCount;
11183
+ const sourceRecordId = sourceRows[mod];
11184
+ const sourceValue = recordsMap[sourceRecordId]?.values[fieldId];
11185
+ updateData.push({
11186
+ path: [targetRecordId, fieldId],
11187
+ value: sourceValue
11188
+ });
11189
+ if (sourceRowIndexPointer <= 0) {
11190
+ sourceRowIndexPointer = sourceRowCount - 1;
11191
+ }
11192
+ else {
11193
+ sourceRowIndexPointer--;
11194
+ }
11195
+ }
11196
+ }
10607
11197
  }
10608
11198
  }
10609
11199
  if (updateData.length > 0) {
@@ -11543,6 +12133,7 @@ class AITableGridBase {
11543
12133
  this.aiMaxSelectOptions = input();
11544
12134
  this.aiReferences = input.required();
11545
12135
  this.aiBuildRenderDataFn = input();
12136
+ this.aiBuildGroupLinearRowsFn = input();
11546
12137
  this.aiGetI18nTextByKey = input();
11547
12138
  this.aiKeywords = input();
11548
12139
  this.aiFrozenColumnCountFn = input();
@@ -11562,6 +12153,7 @@ class AITableGridBase {
11562
12153
  this.aiMoveRecords = output();
11563
12154
  this.aiClick = output();
11564
12155
  this.aiDbClick = output();
12156
+ this.aiRowGroupCollapseClick = output();
11565
12157
  this.fieldMenus = computed(() => {
11566
12158
  const fieldMenusFn = this.aiFieldConfig()?.fieldMenus;
11567
12159
  if (fieldMenusFn && this.aiTable) {
@@ -11658,7 +12250,7 @@ class AITableGridBase {
11658
12250
  }
11659
12251
  }
11660
12252
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
11661
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.10", type: AITableGridBase, isStandalone: true, selector: "ai-table-grid-base", inputs: { aiRecords: { classPropertyName: "aiRecords", publicName: "aiRecords", isSignal: true, isRequired: true, transformFunction: null }, aiFields: { classPropertyName: "aiFields", publicName: "aiFields", isSignal: true, isRequired: true, transformFunction: null }, aiFieldsSizeMap: { classPropertyName: "aiFieldsSizeMap", publicName: "aiFieldsSizeMap", isSignal: true, isRequired: true, transformFunction: null }, aiContextMenuItems: { classPropertyName: "aiContextMenuItems", publicName: "aiContextMenuItems", isSignal: true, isRequired: false, transformFunction: null }, aiFieldConfig: { classPropertyName: "aiFieldConfig", publicName: "aiFieldConfig", isSignal: true, isRequired: false, transformFunction: null }, aiReadonly: { classPropertyName: "aiReadonly", publicName: "aiReadonly", isSignal: true, isRequired: false, transformFunction: null }, aiPlugins: { classPropertyName: "aiPlugins", publicName: "aiPlugins", isSignal: true, isRequired: false, transformFunction: null }, aiMaxFields: { classPropertyName: "aiMaxFields", publicName: "aiMaxFields", isSignal: true, isRequired: false, transformFunction: null }, aiMaxRecords: { classPropertyName: "aiMaxRecords", publicName: "aiMaxRecords", isSignal: true, isRequired: false, transformFunction: null }, aiMaxSelectOptions: { classPropertyName: "aiMaxSelectOptions", publicName: "aiMaxSelectOptions", isSignal: true, isRequired: false, transformFunction: null }, aiReferences: { classPropertyName: "aiReferences", publicName: "aiReferences", isSignal: true, isRequired: true, transformFunction: null }, aiBuildRenderDataFn: { classPropertyName: "aiBuildRenderDataFn", publicName: "aiBuildRenderDataFn", isSignal: true, isRequired: false, transformFunction: null }, aiGetI18nTextByKey: { classPropertyName: "aiGetI18nTextByKey", publicName: "aiGetI18nTextByKey", isSignal: true, isRequired: false, transformFunction: null }, aiKeywords: { classPropertyName: "aiKeywords", publicName: "aiKeywords", isSignal: true, isRequired: false, transformFunction: null }, aiFrozenColumnCountFn: { classPropertyName: "aiFrozenColumnCountFn", publicName: "aiFrozenColumnCountFn", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiRecords: "aiRecordsChange", aiFields: "aiFieldsChange", aiFieldsSizeMap: "aiFieldsSizeMapChange", aiTableInitialized: "aiTableInitialized", aiAddRecord: "aiAddRecord", aiAddField: "aiAddField", aiMoveField: "aiMoveField", aiUpdateFieldValues: "aiUpdateFieldValues", aiSetField: "aiSetField", aiSetFieldWidth: "aiSetFieldWidth", aiSetFieldStatType: "aiSetFieldStatType", aiMoveRecords: "aiMoveRecords", aiClick: "aiClick", aiDbClick: "aiDbClick" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
12253
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.10", type: AITableGridBase, isStandalone: true, selector: "ai-table-grid-base", inputs: { aiRecords: { classPropertyName: "aiRecords", publicName: "aiRecords", isSignal: true, isRequired: true, transformFunction: null }, aiFields: { classPropertyName: "aiFields", publicName: "aiFields", isSignal: true, isRequired: true, transformFunction: null }, aiFieldsSizeMap: { classPropertyName: "aiFieldsSizeMap", publicName: "aiFieldsSizeMap", isSignal: true, isRequired: true, transformFunction: null }, aiContextMenuItems: { classPropertyName: "aiContextMenuItems", publicName: "aiContextMenuItems", isSignal: true, isRequired: false, transformFunction: null }, aiFieldConfig: { classPropertyName: "aiFieldConfig", publicName: "aiFieldConfig", isSignal: true, isRequired: false, transformFunction: null }, aiReadonly: { classPropertyName: "aiReadonly", publicName: "aiReadonly", isSignal: true, isRequired: false, transformFunction: null }, aiPlugins: { classPropertyName: "aiPlugins", publicName: "aiPlugins", isSignal: true, isRequired: false, transformFunction: null }, aiMaxFields: { classPropertyName: "aiMaxFields", publicName: "aiMaxFields", isSignal: true, isRequired: false, transformFunction: null }, aiMaxRecords: { classPropertyName: "aiMaxRecords", publicName: "aiMaxRecords", isSignal: true, isRequired: false, transformFunction: null }, aiMaxSelectOptions: { classPropertyName: "aiMaxSelectOptions", publicName: "aiMaxSelectOptions", isSignal: true, isRequired: false, transformFunction: null }, aiReferences: { classPropertyName: "aiReferences", publicName: "aiReferences", isSignal: true, isRequired: true, transformFunction: null }, aiBuildRenderDataFn: { classPropertyName: "aiBuildRenderDataFn", publicName: "aiBuildRenderDataFn", isSignal: true, isRequired: false, transformFunction: null }, aiBuildGroupLinearRowsFn: { classPropertyName: "aiBuildGroupLinearRowsFn", publicName: "aiBuildGroupLinearRowsFn", isSignal: true, isRequired: false, transformFunction: null }, aiGetI18nTextByKey: { classPropertyName: "aiGetI18nTextByKey", publicName: "aiGetI18nTextByKey", isSignal: true, isRequired: false, transformFunction: null }, aiKeywords: { classPropertyName: "aiKeywords", publicName: "aiKeywords", isSignal: true, isRequired: false, transformFunction: null }, aiFrozenColumnCountFn: { classPropertyName: "aiFrozenColumnCountFn", publicName: "aiFrozenColumnCountFn", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiRecords: "aiRecordsChange", aiFields: "aiFieldsChange", aiFieldsSizeMap: "aiFieldsSizeMapChange", aiTableInitialized: "aiTableInitialized", aiAddRecord: "aiAddRecord", aiAddField: "aiAddField", aiMoveField: "aiMoveField", aiUpdateFieldValues: "aiUpdateFieldValues", aiSetField: "aiSetField", aiSetFieldWidth: "aiSetFieldWidth", aiSetFieldStatType: "aiSetFieldStatType", aiMoveRecords: "aiMoveRecords", aiClick: "aiClick", aiDbClick: "aiDbClick", aiRowGroupCollapseClick: "aiRowGroupCollapseClick" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
11662
12254
  }
11663
12255
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableGridBase, decorators: [{
11664
12256
  type: Component,
@@ -11684,7 +12276,7 @@ class AITableDomGrid extends AITableGridBase {
11684
12276
  });
11685
12277
  }
11686
12278
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableDomGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
11687
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableDomGrid, isStandalone: true, selector: "ai-table-dom-grid", host: { classAttribute: "ai-table-grid ai-table-dom-grid" }, providers: [AITableGridEventService, AITableGridFieldService], usesInheritance: true, ngImport: i0, template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: gridData().fieldsSizeMap[field._id] + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"toggleSelectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: gridData().fieldsSizeMap[field._id] + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SelectOptionPipe, name: "selectOption" }, { kind: "pipe", type: SelectOptionsPipe, name: "selectOptions" }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "ngmodule", type: ThyPopoverModule }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyRate, selector: "thy-rate", inputs: ["thyCount", "thyDisabled", "thyAllowHalf", "thyAllowClear", "thyTooltips", "thyIconTemplate"], outputs: ["thyItemHoverChange"] }, { kind: "component", type: ThyProgress, selector: "thy-progress", inputs: ["thyType", "thySize", "thyValue", "thyMax", "thyTips", "thyShape", "thyGapDegree", "thyGapPosition", "thyStrokeWidth"] }, { kind: "pipe", type: ThyDatePickerFormatPipe, name: "thyDatePickerFormat" }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyCheckboxModule }, { kind: "component", type: i3$1.ThyCheckbox, selector: "thy-checkbox,[thy-checkbox],[thyCheckbox]", inputs: ["thyIndeterminate"] }, { kind: "ngmodule", type: ThyAvatarModule }, { kind: "component", type: i4.ThyAvatar, selector: "thy-avatar", inputs: ["thyShowName", "thySrc", "thyName", "thySize", "thyShowRemove", "thyRemovable", "thyImgClass", "thyDisabled", "thyLoading", "thyFetchPriority"], outputs: ["thyOnRemove", "thyRemove", "thyError", "thySizeChange"] }, { kind: "component", type: i4.ThyAvatarList, selector: "thy-avatar-list", inputs: ["thyMode", "thyAvatarSize"] }, { kind: "pipe", type: IsSelectRecordPipe, name: "isSelectRecord" }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "pipe", type: UserPipe, name: "user" }, { kind: "pipe", type: SelectSettingPipe, name: "selectSetting" }, { kind: "pipe", type: MemberSettingPipe, name: "memberSetting" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
12279
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableDomGrid, isStandalone: true, selector: "ai-table-dom-grid", host: { classAttribute: "ai-table-grid ai-table-dom-grid" }, providers: [AITableGridEventService, AITableGridFieldService], usesInheritance: true, ngImport: i0, template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: gridData().fieldsSizeMap[field._id] + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"toggleSelectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: gridData().fieldsSizeMap[field._id] + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SelectOptionPipe, name: "selectOption" }, { kind: "pipe", type: SelectOptionsPipe, name: "selectOptions" }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "ngmodule", type: ThyPopoverModule }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyRate, selector: "thy-rate", inputs: ["thyValue", "currentValue", "hasHalf", "thyCount", "thyDisabled", "thyAllowHalf", "thyAllowClear", "thyTooltips", "thyIconTemplate"], outputs: ["thyValueChange", "currentValueChange", "hasHalfChange", "thyItemHoverChange"] }, { kind: "component", type: ThyProgress, selector: "thy-progress", inputs: ["thyType", "thySize", "thyValue", "thyMax", "thyTips", "thyShape", "thyGapDegree", "thyGapPosition", "thyStrokeWidth"] }, { kind: "pipe", type: ThyDatePickerFormatPipe, name: "thyDatePickerFormat" }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyCheckboxModule }, { kind: "component", type: i3$1.ThyCheckbox, selector: "thy-checkbox,[thy-checkbox],[thyCheckbox]", inputs: ["thyIndeterminate"] }, { kind: "ngmodule", type: ThyAvatarModule }, { kind: "component", type: i4.ThyAvatar, selector: "thy-avatar", inputs: ["thyShowName", "thySrc", "thyName", "thySize", "thyShowRemove", "thyRemovable", "thyImgClass", "thyDisabled", "thyLoading", "thyFetchPriority"], outputs: ["thyOnRemove", "thyRemove", "thyError", "thySizeChange"] }, { kind: "component", type: i4.ThyAvatarList, selector: "thy-avatar-list", inputs: ["thyMode", "thyAvatarSize"] }, { kind: "pipe", type: IsSelectRecordPipe, name: "isSelectRecord" }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "pipe", type: UserPipe, name: "user" }, { kind: "pipe", type: SelectSettingPipe, name: "selectSetting" }, { kind: "pipe", type: MemberSettingPipe, name: "memberSetting" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
11688
12280
  }
11689
12281
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableDomGrid, decorators: [{
11690
12282
  type: Component,
@@ -12217,11 +12809,7 @@ class AITableDragComponent {
12217
12809
  this.setAuxiliaryLineStyles({
12218
12810
  top: `${nextColumnStartY - scrollPosition.y}px`
12219
12811
  });
12220
- this.draggedData = {
12221
- type: DragType.record,
12222
- recordIds: drag.sourceIds,
12223
- targetIndex: targetRowIndex + 1
12224
- };
12812
+ this.setDragData(DragType.record, drag.sourceIds, targetRowIndex + 1);
12225
12813
  return;
12226
12814
  }
12227
12815
  this.setAuxiliaryLineStyles({
@@ -12230,11 +12818,7 @@ class AITableDragComponent {
12230
12818
  top: `${lineTop}px`,
12231
12819
  left: `${AI_TABLE_ROW_DRAG_ICON_WIDTH}px`
12232
12820
  });
12233
- this.draggedData = {
12234
- type: DragType.record,
12235
- recordIds: drag.sourceIds,
12236
- targetIndex: targetRowIndex
12237
- };
12821
+ this.setDragData(DragType.record, drag.sourceIds, targetRowIndex);
12238
12822
  }
12239
12823
  else {
12240
12824
  this.resetAuxiliaryLine();
@@ -12273,6 +12857,21 @@ class AITableDragComponent {
12273
12857
  }
12274
12858
  });
12275
12859
  }
12860
+ setDragData(type, sourceIds, targetIndex) {
12861
+ const aiTable = this.aiTableGridEventService.aiTable;
12862
+ const linearRows = aiTable.context.linearRows();
12863
+ this.draggedData = {
12864
+ type,
12865
+ recordIds: sourceIds,
12866
+ targetIndex
12867
+ };
12868
+ if (targetIndex === 0) {
12869
+ this.draggedData.beforeRecordId = linearRows[0]._id;
12870
+ }
12871
+ else {
12872
+ this.draggedData.afterRecordId = linearRows[targetIndex - 1]._id;
12873
+ }
12874
+ }
12276
12875
  handleDragEnd() {
12277
12876
  if (this.draggedData) {
12278
12877
  this.dragEnd.emit({ ...this.draggedData });
@@ -12380,7 +12979,7 @@ class AITableGrid extends AITableGridBase {
12380
12979
  this.verticalBarRef = viewChild('verticalBar');
12381
12980
  this.horizontalBarRef = viewChild('horizontalBar');
12382
12981
  this.linearRows = computed(() => {
12383
- return buildGridLinearRows(this.gridData().records, !this.aiReadonly());
12982
+ return buildGridLinearRows(this.gridData().records, !this.aiReadonly(), this.aiTable, this.aiBuildGroupLinearRowsFn?.());
12384
12983
  });
12385
12984
  this.domToolTips = computed(() => {
12386
12985
  const scrollTop = this.aiTable.context.scrollState().scrollTop;
@@ -12440,7 +13039,7 @@ class AITableGrid extends AITableGridBase {
12440
13039
  columnCount: fields.length,
12441
13040
  rowInitSize: AI_TABLE_FIELD_HEAD_HEIGHT,
12442
13041
  columnInitSize: this.aiTable.context.rowHeadWidth(),
12443
- rowIndicesSizeMap: {},
13042
+ rowIndicesSizeMap: this.rowIndicesMap(),
12444
13043
  columnIndicesSizeMap: getColumnIndicesSizeMap(this.aiTable, fields),
12445
13044
  frozenColumnCount: this.frozenColumnCount()
12446
13045
  });
@@ -12478,6 +13077,15 @@ class AITableGrid extends AITableGridBase {
12478
13077
  };
12479
13078
  });
12480
13079
  // rowAddFilterTooltip = getI18nTextByKey(this.aiTable, AITableGridI18nKey.rowAddFilterTooltip);
13080
+ this.rowIndicesMap = computed(() => {
13081
+ const rowIndicesMap = {};
13082
+ this.linearRows().forEach((row, index) => {
13083
+ if (row.type === AITableRowType.blank) {
13084
+ rowIndicesMap[index] = 0;
13085
+ }
13086
+ });
13087
+ return rowIndicesMap;
13088
+ });
12481
13089
  this.actions = {
12482
13090
  updateFieldValues: (data) => {
12483
13091
  this.aiUpdateFieldValues.emit(data);
@@ -12635,7 +13243,7 @@ class AITableGrid extends AITableGridBase {
12635
13243
  let matchedCells = new Set();
12636
13244
  if (keywords) {
12637
13245
  const references = this.aiReferences();
12638
- this.aiTable.records().forEach((record) => {
13246
+ this.aiTable.gridData().records.forEach((record) => {
12639
13247
  this.aiTable.fields().forEach((field) => {
12640
13248
  if (isCellMatchKeywords(this.aiTable, field, record._id, keywords, references)) {
12641
13249
  matchedCells.add(`${record._id}:${field._id}`);
@@ -12873,7 +13481,9 @@ class AITableGrid extends AITableGridBase {
12873
13481
  switch (targetName) {
12874
13482
  case AI_TABLE_ROW_ADD_BUTTON: {
12875
13483
  clearCoverCell(this.aiTable);
12876
- this.addRecord();
13484
+ this.addRecord({
13485
+ forGroupId: targetNameDetail.source
13486
+ });
12877
13487
  const { isCanFullRender, offsetY } = this.coordinate().getAddRowButtonIsFullRenderInfo(this.aiTable);
12878
13488
  if (!isCanFullRender) {
12879
13489
  this.scrollAction({
@@ -12939,6 +13549,13 @@ class AITableGrid extends AITableGridBase {
12939
13549
  }
12940
13550
  }
12941
13551
  break;
13552
+ case AI_TABLE_ROW_GROUP_COLLAPSE_BUTTON: {
13553
+ const groupId = targetNameDetail.source;
13554
+ if (groupId) {
13555
+ this.aiRowGroupCollapseClick.emit(groupId);
13556
+ }
13557
+ break;
13558
+ }
12942
13559
  }
12943
13560
  return;
12944
13561
  }
@@ -13041,14 +13658,46 @@ class AITableGrid extends AITableGridBase {
13041
13658
  });
13042
13659
  this.resizeObserver.observe(this.containerElement());
13043
13660
  }
13661
+ getNextRecordRowId(currentRowIndex, event) {
13662
+ const linearRows = this.aiTable.context.linearRows();
13663
+ if (event.key === 'ArrowUp') {
13664
+ let nextRowIndex = currentRowIndex - 1;
13665
+ let findFlag = false;
13666
+ while (nextRowIndex > -1 && !findFlag) {
13667
+ const row = linearRows[nextRowIndex];
13668
+ if (row.type === AITableRowType.record) {
13669
+ findFlag = true;
13670
+ }
13671
+ else {
13672
+ nextRowIndex--;
13673
+ }
13674
+ }
13675
+ return findFlag ? linearRows[nextRowIndex]._id : null;
13676
+ }
13677
+ if (event.key === 'ArrowDown') {
13678
+ let nextRowIndex = currentRowIndex + 1;
13679
+ let findFlag = false;
13680
+ while (nextRowIndex < linearRows.length && !findFlag) {
13681
+ const row = linearRows[nextRowIndex];
13682
+ if (row.type === AITableRowType.record) {
13683
+ findFlag = true;
13684
+ }
13685
+ else {
13686
+ nextRowIndex++;
13687
+ }
13688
+ }
13689
+ return findFlag ? linearRows[nextRowIndex]._id : null;
13690
+ }
13691
+ return null;
13692
+ }
13044
13693
  getNextCell(currentCell, event) {
13045
13694
  const { rowIndex, columnIndex } = AITable.getCellIndex(this.aiTable, currentCell) || {};
13046
13695
  let nextCellPath = null;
13047
- if (event.key === 'ArrowUp' && rowIndex) {
13048
- nextCellPath = [this.aiTable.gridData().records[rowIndex - 1]._id, currentCell[1]];
13049
- }
13050
- if (event.key === 'ArrowDown' && rowIndex < this.gridData().records.length - 1) {
13051
- nextCellPath = [this.aiTable.gridData().records[rowIndex + 1]._id, currentCell[1]];
13696
+ if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
13697
+ const nextRowId = this.getNextRecordRowId(rowIndex, event);
13698
+ if (nextRowId) {
13699
+ nextCellPath = [nextRowId, currentCell[1]];
13700
+ }
13052
13701
  }
13053
13702
  if (event.key === 'ArrowLeft' && columnIndex) {
13054
13703
  nextCellPath = [currentCell[0], this.aiTable.gridData().fields[columnIndex - 1]._id];
@@ -13065,6 +13714,14 @@ class AITableGrid extends AITableGridBase {
13065
13714
  if (this.aiReadonly()) {
13066
13715
  return;
13067
13716
  }
13717
+ const focused = document.activeElement;
13718
+ if (!focused) {
13719
+ return;
13720
+ }
13721
+ const hasAITableGrid = focused.querySelector('ai-table-grid') !== null;
13722
+ if (!hasAITableGrid) {
13723
+ return;
13724
+ }
13068
13725
  const hasSelectedCells = this.aiTable.selection().selectedCells.size > 0;
13069
13726
  if (!hasSelectedCells) {
13070
13727
  return;
@@ -13078,7 +13735,10 @@ class AITableGrid extends AITableGridBase {
13078
13735
  if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
13079
13736
  return;
13080
13737
  }
13081
- event.preventDefault();
13738
+ const hasContentEditable = target.contentEditable === 'true';
13739
+ if (hasContentEditable) {
13740
+ return;
13741
+ }
13082
13742
  const isCopyOrPaste = (event.ctrlKey || event.metaKey) && (event.key === 'c' || event.key === 'v');
13083
13743
  const isDeleteOrBackspace = event.key === 'Backspace' || event.key === 'Delete';
13084
13744
  const isDirectionKey = event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'ArrowLeft' || event.key === 'ArrowRight';
@@ -13119,6 +13779,7 @@ class AITableGrid extends AITableGridBase {
13119
13779
  }
13120
13780
  }
13121
13781
  }
13782
+ event.preventDefault();
13122
13783
  return;
13123
13784
  }
13124
13785
  if (isCopyOrPaste) {
@@ -13128,10 +13789,12 @@ class AITableGrid extends AITableGridBase {
13128
13789
  else if (event.key === 'v') {
13129
13790
  this.pasteCells();
13130
13791
  }
13792
+ event.preventDefault();
13131
13793
  return;
13132
13794
  }
13133
13795
  if (isDeleteOrBackspace) {
13134
13796
  clearCells(this.aiTable, this.actions);
13797
+ event.preventDefault();
13135
13798
  return;
13136
13799
  }
13137
13800
  // quick enter cell editor
@@ -13152,6 +13815,7 @@ class AITableGrid extends AITableGridBase {
13152
13815
  this.aiUpdateFieldValues.emit(value);
13153
13816
  }
13154
13817
  });
13818
+ event.preventDefault();
13155
13819
  }
13156
13820
  });
13157
13821
  }
@@ -13228,10 +13892,11 @@ class AITableGrid extends AITableGridBase {
13228
13892
  }
13229
13893
  break;
13230
13894
  case DragType.record:
13231
- if (data.recordIds && isNumber(data.targetIndex)) {
13895
+ if (data.recordIds && (data.beforeRecordId || data.afterRecordId)) {
13232
13896
  this.aiMoveRecords.emit({
13233
- recordIds: Array.from(data.recordIds).map((id) => [id]),
13234
- newPath: [data.targetIndex]
13897
+ recordIds: Array.from(data.recordIds),
13898
+ beforeRecordId: data.beforeRecordId,
13899
+ afterRecordId: data.afterRecordId
13235
13900
  });
13236
13901
  }
13237
13902
  return;
@@ -13326,5 +13991,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
13326
13991
  * Generated bundle index. Do not edit.
13327
13992
  */
13328
13993
 
13329
- export { AITable, AITableActionIcon, AITableAddField, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableBackground, AITableCellAttachment, AITableCellCheckbox, AITableCellLink, AITableCellProgress, AITableCellRate, AITableCellRichText, AITableCellText, AITableCells, AITableCheckType, AITableColumnHeads, AITableContextMenu, AITableDomGrid, AITableFieldHead, AITableFieldIcon, AITableFieldIsSameOptionPipe, AITableFieldSetting, AITableFrozenCells, AITableFrozenColumnHeads, AITableFrozenFieldShadow, AITableFrozenPlaceholderCells, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridI18nKey, AITableGridI18nText, AITableHoverRowHeads, AITableIcon, AITableMemberType, AITableMouseDownType, AITableOtherRows, AITablePlaceholderCells, AITableQueries, AITableRenderer, AITableRowType, AITableScrollableGroup, AITableSelectAllState, AITableTextComponent, AI_TABLE_ACTION_COMMON_RADIUS, AI_TABLE_ACTION_COMMON_RIGHT_PADDING, AI_TABLE_ACTION_COMMON_SIZE, AI_TABLE_AUTO_SCROLL_BOTTOM_THRESHOLD, AI_TABLE_AUTO_SCROLL_LEFT_THRESHOLD, AI_TABLE_AUTO_SCROLL_RIGHT_THRESHOLD, AI_TABLE_AUTO_SCROLL_TOP_THRESHOLD, AI_TABLE_BLANK, AI_TABLE_CELL, AI_TABLE_CELL_ACTIVE_BORDER_WIDTH, AI_TABLE_CELL_ADD_ITEM_BUTTON_SIZE, AI_TABLE_CELL_ATTACHMENT_ADD, AI_TABLE_CELL_ATTACHMENT_FILE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EDIT, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, AI_TABLE_CELL_FIELD_ITEM_HEIGHT, AI_TABLE_CELL_LINE_BORDER, AI_TABLE_CELL_MAX_ROW_COUNT, AI_TABLE_CELL_MEMBER_ITEM_HEIGHT, AI_TABLE_CELL_MEMBER_ITEM_PADDING, AI_TABLE_CELL_MEMBER_MAX_HEIGHT, AI_TABLE_CELL_MULTI_DOT_RADIUS, AI_TABLE_CELL_MULTI_ITEM_MARGIN_LEFT, AI_TABLE_CELL_MULTI_ITEM_MARGIN_TOP, AI_TABLE_CELL_MULTI_ITEM_MIN_WIDTH, AI_TABLE_CELL_MULTI_PADDING_LEFT, AI_TABLE_CELL_MULTI_PADDING_TOP, AI_TABLE_CELL_PADDING, AI_TABLE_COMMON_FONT_SIZE, AI_TABLE_DEFAULT_COLUMN_WIDTH, AI_TABLE_DOT_RADIUS, AI_TABLE_FIELD_ADD_BUTTON, AI_TABLE_FIELD_ADD_BUTTON_WIDTH, AI_TABLE_FIELD_HEAD, AI_TABLE_FIELD_HEAD_HEIGHT, AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE, AI_TABLE_FIELD_HEAD_MORE, AI_TABLE_FIELD_HEAD_OPACITY_LINE, AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX, AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH, AI_TABLE_FIELD_ITEM_MARGIN_RIGHT, AI_TABLE_FIELD_MAX_WIDTH, AI_TABLE_FIELD_MIDDLE_WIDTH, AI_TABLE_FIELD_MINI_WIDTH, AI_TABLE_FIELD_MIN_WIDTH, AI_TABLE_FIELD_STAT_BG, AI_TABLE_FIELD_STAT_CONTAINER_HEIGHT, AI_TABLE_FIELD_STAT_INNER_HEIGHT, AI_TABLE_FILE_ICON_ITEM_HEIGHT, AI_TABLE_FILE_ICON_SIZE, AI_TABLE_FILL_HANDLE, AI_TABLE_GRID_FIELD_SERVICE_MAP, AI_TABLE_ICON_COMMON_SIZE, AI_TABLE_INDEX_FIELD_TEXT, AI_TABLE_MEMBER_AVATAR_SIZE, AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT, AI_TABLE_MEMBER_ITEM_PADDING_RIGHT, AI_TABLE_MIN_TEXT_WIDTH, AI_TABLE_OFFSET, AI_TABLE_OPTION_ITEM_FONT_SIZE, AI_TABLE_OPTION_ITEM_HEIGHT, AI_TABLE_OPTION_ITEM_PADDING, AI_TABLE_OPTION_ITEM_RADIUS, AI_TABLE_OPTION_MULTI_ITEM_FONT_SIZE, AI_TABLE_PIECE_RADIUS, AI_TABLE_PIECE_WIDTH, AI_TABLE_POPOVER_LEFT_OFFSET, AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS, AI_TABLE_PROGRESS_BAR_HEIGHT, AI_TABLE_PROGRESS_BAR_POINTER_HEIGHT, AI_TABLE_PROGRESS_BAR_POINTER_WIDTH, AI_TABLE_PROGRESS_BAR_RADIUS, AI_TABLE_PROGRESS_TEXT_WIDTH, AI_TABLE_RATE_MAX, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_DRAG, AI_TABLE_ROW_DRAG_ICON_WIDTH, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_HEAD_WIDTH_AND_DRAG_ICON_WIDTH, AI_TABLE_ROW_HEIGHT, AI_TABLE_ROW_SELECT_CHECKBOX, AI_TABLE_SCROLL_BAR_PADDING, AI_TABLE_SCROLL_BAR_SIZE, AI_TABLE_TAG_FONT_SIZE, AI_TABLE_TAG_PADDING, AI_TABLE_TEXT_GAP, AI_TABLE_TEXT_LINE_HEIGHT, AbstractEditCellEditor, AddOutlinedPath, AngleDownPath, AttachmentField, AttachmentPath, CellDrawer, Check, CheckboxMenuSort, Colors, ColumnCalendarFilledPath, ColumnCheckboxFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnRichTextFilledPath, ColumnSelectFilledPath, ColumnTextFilledPath, Coordinate, CoverCellBase, DBL_CLICK_EDIT_TYPE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_STYLE, DEFAULT_FONT_WEIGHT, DEFAULT_ICON_SHAPE, DEFAULT_ICON_SIZE, DEFAULT_POINT_POSITION, DEFAULT_SCROLL_STATE, DEFAULT_TEXT_ALIGN_CENTER, DEFAULT_TEXT_ALIGN_LEFT, DEFAULT_TEXT_ALIGN_RIGHT, DEFAULT_TEXT_DECORATION, DEFAULT_TEXT_ELLIPSIS, DEFAULT_TEXT_FILL, DEFAULT_TEXT_LINE_HEIGHT, DEFAULT_TEXT_LISTENING, DEFAULT_TEXT_MAX_CACHE, DEFAULT_TEXT_MAX_HEIGHT, DEFAULT_TEXT_SCALE, DEFAULT_TEXT_TRANSFORMS_ENABLED, DEFAULT_TEXT_VERTICAL_ALIGN_MIDDLE, DEFAULT_TEXT_VERTICAL_ALIGN_TOP, DEFAULT_TEXT_WRAP, DEFAULT_WRAP_TEXT_MAX_ROW, DateCellEditorComponent, DateField, DepartmentOutlinedPath, Drawer, EditPath, FONT_SIZE_SM, FieldModelMap, IconPathMap, IsSelectRecordPipe, KO_CONTAINER_TOKEN, KoComponent, KoContainer, KoShape, KoShapeTypes, KoStage, LinkCellEditorComponent, LinkField, MIN_COLUMN_WIDTH, MemberField, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, NumberField, ProgressField, RateField, RendererContext, RichTextField, RowDragPath, RowHeight, SelectCellEditorComponent, SelectField, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextField, TextMeasure, Unchecked, UserPipe, WebOutlinedPath, aiTableFragmentAttribute, aiTableImageConfigToKonvaConfig, aiTableRectConfigToKonvaConfig, aiTableTextConfigToKonvaConfig, applyNodeProps, buildClipboardData, buildGridData, buildGridLinearRows, castToString, cellDrawer, clearCells, clearCoverCell, clearSelectedCells, clearSelection, clearSelectionFields, clearSelectionRecords, closeEditingCell, closeExpendCell, compareNumber, compareOption, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, createListener, dragFillHighlightArea, drawer, expandCell, extractLinkUrl, extractText, generateNewName, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getCoverCell, getDateFieldValues, getDefaultFieldOptions, getDefaultFieldValue, getDefaultI18nTextByKey, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getFieldOptionMap, getFieldOptions, getFieldValue, getFileThumbnailSvgString, getFillDirection, getHoverEditorBoxOffset, getHoverEditorSpace, getI18nTextByKey, getMousePosition, getName, getOptionsByFieldAndRecords, getPlaceHolderCellsConfigs, getStartAndEndCell, getSystemFieldValue, getTargetName, getTextWidth, getVisibleRangeInfo, graphemeSplitter, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isActiveCell, isArrayField, isCellMatchKeywords, isClipboardReadSupported, isClipboardReadTextSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isDateFiled, isEmptyOrNot, isMac, isMeetFilter, isNumberFiled, isSameFieldOption, isSelectedField, isSystemField, isVirtualKey, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, performFill, processPastedValueForSelect, readFromClipboard, scrollMax, scrollToMatchedCell, selectCells, selectField, setActiveCell, setEditingCell, setExpandCellInfo, setMouseStyle, setSelection, shortIdCreator, shortIdsCreator, statDateRangeOfDays, statDateRangeOfMonths, statEarliestTime, statLatestTime, stringInclude, textDataCache, toAttachmentFieldValue, toDateFieldValue, toLinkFieldValue, toMemberFieldValue, toNumberFieldValue, toProgressFieldValue, toRateFieldValue, toRichTextFieldValue, toSelectFieldValue, toTextFieldValue, toggleSelectAllRecords, toggleSelectRecord, transformToCellText, updatePicture, writeToAITable, writeToClipboard, zhIntlCollator };
13994
+ export { AITable, AITableActionIcon, AITableAddField, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableBackground, AITableCellAttachment, AITableCellCheckbox, AITableCellLink, AITableCellProgress, AITableCellRate, AITableCellRichText, AITableCellText, AITableCells, AITableCheckType, AITableColumnHeads, AITableContextMenu, AITableDomGrid, AITableFieldHead, AITableFieldIcon, AITableFieldIsSameOptionPipe, AITableFieldSetting, AITableFrozenCells, AITableFrozenColumnHeads, AITableFrozenGroups, AITableFrozenPlaceholderCells, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridI18nKey, AITableGridI18nText, AITableGroups, AITableHoverRowHeads, AITableIcon, AITableMemberType, AITableMouseDownType, AITableOtherRows, AITablePlaceholderCells, AITableQueries, AITableRenderer, AITableRowType, AITableScrollableGroup, AITableSelectAllState, AITableShadow, AITableTextComponent, AI_TABLE_ACTION_COMMON_RADIUS, AI_TABLE_ACTION_COMMON_RIGHT_PADDING, AI_TABLE_ACTION_COMMON_SIZE, AI_TABLE_AUTO_SCROLL_BOTTOM_THRESHOLD, AI_TABLE_AUTO_SCROLL_LEFT_THRESHOLD, AI_TABLE_AUTO_SCROLL_RIGHT_THRESHOLD, AI_TABLE_AUTO_SCROLL_TOP_THRESHOLD, AI_TABLE_BLANK, AI_TABLE_CELL, AI_TABLE_CELL_ACTIVE_BORDER_WIDTH, AI_TABLE_CELL_ADD_ITEM_BUTTON_SIZE, AI_TABLE_CELL_ATTACHMENT_ADD, AI_TABLE_CELL_ATTACHMENT_FILE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EDIT, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, AI_TABLE_CELL_FIELD_ITEM_HEIGHT, AI_TABLE_CELL_LINE_BORDER, AI_TABLE_CELL_MAX_ROW_COUNT, AI_TABLE_CELL_MEMBER_ITEM_HEIGHT, AI_TABLE_CELL_MEMBER_ITEM_PADDING, AI_TABLE_CELL_MEMBER_MAX_HEIGHT, AI_TABLE_CELL_MULTI_DOT_RADIUS, AI_TABLE_CELL_MULTI_ITEM_MARGIN_LEFT, AI_TABLE_CELL_MULTI_ITEM_MARGIN_TOP, AI_TABLE_CELL_MULTI_ITEM_MIN_WIDTH, AI_TABLE_CELL_MULTI_PADDING_LEFT, AI_TABLE_CELL_MULTI_PADDING_TOP, AI_TABLE_CELL_PADDING, AI_TABLE_COMMON_FONT_SIZE, AI_TABLE_DEFAULT_COLUMN_WIDTH, AI_TABLE_DOT_RADIUS, AI_TABLE_FIELD_ADD_BUTTON, AI_TABLE_FIELD_ADD_BUTTON_WIDTH, AI_TABLE_FIELD_HEAD, AI_TABLE_FIELD_HEAD_HEIGHT, AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE, AI_TABLE_FIELD_HEAD_MORE, AI_TABLE_FIELD_HEAD_OPACITY_LINE, AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX, AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH, AI_TABLE_FIELD_ITEM_MARGIN_RIGHT, AI_TABLE_FIELD_MAX_WIDTH, AI_TABLE_FIELD_MIDDLE_WIDTH, AI_TABLE_FIELD_MINI_WIDTH, AI_TABLE_FIELD_MIN_WIDTH, AI_TABLE_FIELD_STAT_BG, AI_TABLE_FIELD_STAT_CONTAINER_HEIGHT, AI_TABLE_FIELD_STAT_INNER_HEIGHT, AI_TABLE_FILE_ICON_ITEM_HEIGHT, AI_TABLE_FILE_ICON_SIZE, AI_TABLE_FILL_HANDLE, AI_TABLE_GRID_FIELD_SERVICE_MAP, AI_TABLE_GROUP_MAX_LEVEL, AI_TABLE_ICON_COMMON_SIZE, AI_TABLE_INDEX_FIELD_TEXT, AI_TABLE_MEMBER_AVATAR_SIZE, AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT, AI_TABLE_MEMBER_ITEM_PADDING_RIGHT, AI_TABLE_MIN_TEXT_WIDTH, AI_TABLE_OFFSET, AI_TABLE_OPTION_ITEM_FONT_SIZE, AI_TABLE_OPTION_ITEM_HEIGHT, AI_TABLE_OPTION_ITEM_PADDING, AI_TABLE_OPTION_ITEM_RADIUS, AI_TABLE_OPTION_MULTI_ITEM_FONT_SIZE, AI_TABLE_PIECE_RADIUS, AI_TABLE_PIECE_WIDTH, AI_TABLE_POPOVER_LEFT_OFFSET, AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS, AI_TABLE_PROGRESS_BAR_HEIGHT, AI_TABLE_PROGRESS_BAR_POINTER_HEIGHT, AI_TABLE_PROGRESS_BAR_POINTER_WIDTH, AI_TABLE_PROGRESS_BAR_RADIUS, AI_TABLE_PROGRESS_TEXT_WIDTH, AI_TABLE_RATE_MAX, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_DRAG, AI_TABLE_ROW_DRAG_ICON_WIDTH, AI_TABLE_ROW_GROUP_COLLAPSE_BUTTON, AI_TABLE_ROW_GROUP_OFFSET, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_HEAD_WIDTH_AND_DRAG_ICON_WIDTH, AI_TABLE_ROW_HEIGHT, AI_TABLE_ROW_SELECT_CHECKBOX, AI_TABLE_SCROLL_BAR_PADDING, AI_TABLE_SCROLL_BAR_SIZE, AI_TABLE_SHADOW_DEFAULT_WIDTH, AI_TABLE_TAG_FONT_SIZE, AI_TABLE_TAG_PADDING, AI_TABLE_TEXT_GAP, AI_TABLE_TEXT_LINE_HEIGHT, AbstractEditCellEditor, AddOutlinedPath, AngleDownPath, AngleRightPath, AttachmentField, AttachmentPath, CellDrawer, Check, CheckboxMenuSort, Colors, ColumnCalendarFilledPath, ColumnCheckboxFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnRichTextFilledPath, ColumnSelectFilledPath, ColumnTextFilledPath, Coordinate, CoverCellBase, DBL_CLICK_EDIT_TYPE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_STYLE, DEFAULT_FONT_WEIGHT, DEFAULT_ICON_SHAPE, DEFAULT_ICON_SIZE, DEFAULT_POINT_POSITION, DEFAULT_SCROLL_STATE, DEFAULT_TEXT_ALIGN_CENTER, DEFAULT_TEXT_ALIGN_LEFT, DEFAULT_TEXT_ALIGN_RIGHT, DEFAULT_TEXT_DECORATION, DEFAULT_TEXT_ELLIPSIS, DEFAULT_TEXT_FILL, DEFAULT_TEXT_LINE_HEIGHT, DEFAULT_TEXT_LISTENING, DEFAULT_TEXT_MAX_CACHE, DEFAULT_TEXT_MAX_HEIGHT, DEFAULT_TEXT_SCALE, DEFAULT_TEXT_TRANSFORMS_ENABLED, DEFAULT_TEXT_VERTICAL_ALIGN_MIDDLE, DEFAULT_TEXT_VERTICAL_ALIGN_TOP, DEFAULT_TEXT_WRAP, DEFAULT_WRAP_TEXT_MAX_ROW, DateCellEditorComponent, DateField, DepartmentOutlinedPath, Drawer, EditPath, FONT_SIZE_SM, FieldModelMap, IconPathMap, IsSelectRecordPipe, KO_CONTAINER_TOKEN, KoComponent, KoContainer, KoShape, KoShapeTypes, KoStage, LinkCellEditorComponent, LinkField, MIN_COLUMN_WIDTH, MemberField, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, NumberField, ProgressField, RateField, RendererContext, RichTextField, RowDragPath, RowHeight, SelectCellEditorComponent, SelectField, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextField, TextMeasure, Unchecked, UserPipe, WebOutlinedPath, aiTableFragmentAttribute, aiTableImageConfigToKonvaConfig, aiTableRectConfigToKonvaConfig, aiTableTextConfigToKonvaConfig, applyNodeProps, buildClipboardData, buildGridData, buildGridLinearRows, castToString, cellDrawer, clearCells, clearCoverCell, clearSelectedCells, clearSelection, clearSelectionFields, clearSelectionRecords, closeEditingCell, closeExpendCell, compareNumber, compareOption, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, createListener, dragFillHighlightArea, drawer, expandCell, extractLinkUrl, extractText, generateNewName, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getCoverCell, getDateFieldValues, getDefaultFieldOptions, getDefaultFieldValue, getDefaultI18nTextByKey, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getFieldOptionMap, getFieldOptions, getFieldValue, getFileThumbnailSvgString, getFillDirection, getGroupLastRecordIndex, getHoverEditorBoxOffset, getHoverEditorSpace, getI18nTextByKey, getMousePosition, getName, getOptionsByFieldAndRecords, getPlaceHolderCellsConfigs, getStartAndEndCell, getSystemFieldValue, getTargetName, getTextWidth, getVisibleRangeInfo, graphemeSplitter, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isActiveCell, isArrayField, isCellMatchKeywords, isClipboardReadSupported, isClipboardReadTextSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isDateFiled, isEmptyOrNot, isMac, isMeetFilter, isNumberFiled, isSameFieldOption, isSelectedField, isSystemField, isVirtualKey, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, performFill, processPastedValueForSelect, readFromClipboard, scrollMax, scrollToMatchedCell, selectCells, selectField, setActiveCell, setEditingCell, setExpandCellInfo, setMouseStyle, setSelection, shortIdCreator, shortIdsCreator, statDateRangeOfDays, statDateRangeOfMonths, statEarliestTime, statLatestTime, stringInclude, textDataCache, toAttachmentFieldValue, toDateFieldValue, toLinkFieldValue, toMemberFieldValue, toNumberFieldValue, toProgressFieldValue, toRateFieldValue, toRichTextFieldValue, toSelectFieldValue, toTextFieldValue, toggleSelectAllRecords, toggleSelectRecord, transformToCellText, updatePicture, writeToAITable, writeToClipboard, zhIntlCollator };
13330
13995
  //# sourceMappingURL=ai-table-grid.mjs.map