@ai-table/grid 0.0.28 → 0.0.30

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 (112) hide show
  1. package/components/context-menu/context-menu.component.d.ts.map +1 -1
  2. package/constants/table.d.ts +1 -1
  3. package/constants/table.d.ts.map +1 -1
  4. package/core/types/ai-table.d.ts +7 -15
  5. package/core/types/ai-table.d.ts.map +1 -1
  6. package/core/types/core.d.ts +3 -3
  7. package/core/types/core.d.ts.map +1 -1
  8. package/core/utils/common.d.ts.map +1 -1
  9. package/core/utils/queries.d.ts +2 -2
  10. package/core/utils/queries.d.ts.map +1 -1
  11. package/esm2022/components/context-menu/context-menu.component.mjs +4 -11
  12. package/esm2022/constants/table.mjs +2 -2
  13. package/esm2022/core/types/ai-table.mjs +22 -16
  14. package/esm2022/core/types/core.mjs +1 -1
  15. package/esm2022/core/utils/common.mjs +6 -5
  16. package/esm2022/core/utils/queries.mjs +1 -1
  17. package/esm2022/dom-grid.component.mjs +3 -3
  18. package/esm2022/grid-base.component.mjs +1 -4
  19. package/esm2022/grid.component.mjs +46 -10
  20. package/esm2022/renderer/creations/create-active-cell-border.mjs +6 -3
  21. package/esm2022/renderer/creations/create-cells.mjs +55 -25
  22. package/esm2022/renderer/renderer.component.mjs +7 -3
  23. package/esm2022/services/event.service.mjs +3 -2
  24. package/esm2022/services/index.mjs +1 -2
  25. package/esm2022/services/selection.service.mjs +41 -16
  26. package/esm2022/types/grid.mjs +1 -1
  27. package/esm2022/types/index.mjs +2 -1
  28. package/esm2022/types/view.mjs +18 -0
  29. package/esm2022/utils/field/model/date.mjs +64 -0
  30. package/esm2022/utils/field/model/field.mjs +38 -0
  31. package/esm2022/utils/field/model/index.mjs +25 -0
  32. package/esm2022/utils/field/model/link.mjs +33 -0
  33. package/esm2022/utils/field/model/member.mjs +57 -0
  34. package/esm2022/utils/field/model/number.mjs +32 -0
  35. package/esm2022/utils/field/model/progress.mjs +38 -0
  36. package/esm2022/utils/field/model/rate.mjs +26 -0
  37. package/esm2022/utils/field/model/select.mjs +56 -0
  38. package/esm2022/utils/field/model/text.mjs +27 -0
  39. package/esm2022/utils/field/operate.mjs +47 -0
  40. package/esm2022/utils/index.mjs +4 -2
  41. package/esm2022/utils/match-keywords.mjs +11 -0
  42. package/fesm2022/ai-table-grid.mjs +546 -146
  43. package/fesm2022/ai-table-grid.mjs.map +1 -1
  44. package/grid-base.component.d.ts +0 -2
  45. package/grid-base.component.d.ts.map +1 -1
  46. package/grid.component.d.ts +5 -0
  47. package/grid.component.d.ts.map +1 -1
  48. package/package.json +1 -1
  49. package/renderer/creations/create-active-cell-border.d.ts.map +1 -1
  50. package/renderer/creations/create-cells.d.ts.map +1 -1
  51. package/renderer/renderer.component.d.ts +5 -3
  52. package/renderer/renderer.component.d.ts.map +1 -1
  53. package/services/event.service.d.ts.map +1 -1
  54. package/services/index.d.ts +0 -1
  55. package/services/index.d.ts.map +1 -1
  56. package/services/selection.service.d.ts +3 -2
  57. package/services/selection.service.d.ts.map +1 -1
  58. package/types/grid.d.ts +6 -5
  59. package/types/grid.d.ts.map +1 -1
  60. package/types/index.d.ts +1 -0
  61. package/types/index.d.ts.map +1 -1
  62. package/types/view.d.ts +23 -0
  63. package/types/view.d.ts.map +1 -0
  64. package/utils/field/model/date.d.ts +9 -0
  65. package/utils/field/model/date.d.ts.map +1 -0
  66. package/utils/field/model/field.d.ts +9 -0
  67. package/utils/field/model/field.d.ts.map +1 -0
  68. package/utils/field/{index.d.ts → model/index.d.ts} +1 -1
  69. package/utils/field/model/index.d.ts.map +1 -0
  70. package/utils/field/model/link.d.ts +9 -0
  71. package/utils/field/model/link.d.ts.map +1 -0
  72. package/utils/field/model/member.d.ts +9 -0
  73. package/utils/field/model/member.d.ts.map +1 -0
  74. package/utils/field/model/number.d.ts +8 -0
  75. package/utils/field/model/number.d.ts.map +1 -0
  76. package/utils/field/model/progress.d.ts +9 -0
  77. package/utils/field/model/progress.d.ts.map +1 -0
  78. package/utils/field/model/rate.d.ts +8 -0
  79. package/utils/field/model/rate.d.ts.map +1 -0
  80. package/utils/field/model/select.d.ts +9 -0
  81. package/utils/field/model/select.d.ts.map +1 -0
  82. package/utils/field/model/text.d.ts +8 -0
  83. package/utils/field/model/text.d.ts.map +1 -0
  84. package/utils/field/operate.d.ts +9 -0
  85. package/utils/field/operate.d.ts.map +1 -0
  86. package/utils/index.d.ts +3 -1
  87. package/utils/index.d.ts.map +1 -1
  88. package/utils/match-keywords.d.ts +4 -0
  89. package/utils/match-keywords.d.ts.map +1 -0
  90. package/esm2022/services/match-cell.service.mjs +0 -45
  91. package/esm2022/utils/field/field.mjs +0 -3
  92. package/esm2022/utils/field/index.mjs +0 -22
  93. package/esm2022/utils/field/link.mjs +0 -12
  94. package/esm2022/utils/field/member.mjs +0 -19
  95. package/esm2022/utils/field/progress.mjs +0 -12
  96. package/esm2022/utils/field/select.mjs +0 -16
  97. package/esm2022/utils/field/text.mjs +0 -12
  98. package/services/match-cell.service.d.ts +0 -13
  99. package/services/match-cell.service.d.ts.map +0 -1
  100. package/utils/field/field.d.ts +0 -5
  101. package/utils/field/field.d.ts.map +0 -1
  102. package/utils/field/index.d.ts.map +0 -1
  103. package/utils/field/link.d.ts +0 -6
  104. package/utils/field/link.d.ts.map +0 -1
  105. package/utils/field/member.d.ts +0 -6
  106. package/utils/field/member.d.ts.map +0 -1
  107. package/utils/field/progress.d.ts +0 -6
  108. package/utils/field/progress.d.ts.map +0 -1
  109. package/utils/field/select.d.ts +0 -6
  110. package/utils/field/select.d.ts.map +0 -1
  111. package/utils/field/text.d.ts +0 -6
  112. package/utils/field/text.d.ts.map +0 -1
@@ -6,7 +6,7 @@ import ObjectID from 'bson-objectid';
6
6
  import { customAlphabet } from 'nanoid';
7
7
  import * as _ from 'lodash';
8
8
  import ___default, { isNumber, includes, values, isString, isNil } from 'lodash';
9
- import { isUndefinedOrNull, isArray, isEmpty as isEmpty$1, isObject } from 'ngx-tethys/util';
9
+ import { isUndefinedOrNull, isArray, isEmpty as isEmpty$1, isObject, TinyDate, helpers } from 'ngx-tethys/util';
10
10
  import * as i1 from '@angular/forms';
11
11
  import { FormsModule } from '@angular/forms';
12
12
  import { ThyDatePicker, ThyDatePickerFormatPipe } from 'ngx-tethys/date-picker';
@@ -43,6 +43,7 @@ import { ThyProgress } from 'ngx-tethys/progress';
43
43
  import { ThyDivider } from 'ngx-tethys/divider';
44
44
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
45
45
  import { LRUCache } from 'lru-cache';
46
+ import { fromUnixTime, subDays } from 'date-fns';
46
47
  import Konva from 'konva';
47
48
  import { Shape } from 'konva/lib/Shape';
48
49
  import { Sprite } from 'konva/lib/shapes/Sprite';
@@ -98,32 +99,38 @@ const AITable = {
98
99
  return aiTable.records();
99
100
  },
100
101
  getActiveCell(aiTable) {
101
- const selection = aiTable.selection();
102
- let selectedCells = [];
103
- for (let [recordId, fieldIds] of selection.selectedCells.entries()) {
104
- for (let fieldId of Object.keys(fieldIds)) {
105
- if (fieldIds[fieldId]) {
106
- selectedCells.push({
107
- recordId,
108
- fieldId
109
- });
110
- }
111
- }
102
+ return aiTable.selection().activeCell;
103
+ },
104
+ getActiveRecordIds(aiTable) {
105
+ const selectedRecords = aiTable.selection().selectedRecords;
106
+ const selectedCells = aiTable.selection().selectedCells;
107
+ let selectedRecordIds = [];
108
+ if (selectedRecords.size > 0) {
109
+ selectedRecordIds = [...selectedRecords.keys()];
110
+ }
111
+ else if (selectedCells.size > 0) {
112
+ selectedRecordIds = [...selectedCells].map((item) => item.split(':')[0]);
112
113
  }
113
- return selectedCells ? selectedCells[0] : null;
114
+ else {
115
+ selectedRecordIds = [];
116
+ }
117
+ return selectedRecordIds;
114
118
  },
115
119
  isCellVisible(aiTable, cell) {
116
120
  const visibleRowIndexMap = aiTable.context.visibleRowsIndexMap();
117
121
  const visibleColumnIndexMap = aiTable.context.visibleColumnsMap();
118
- return visibleRowIndexMap.has(cell.recordId) && visibleColumnIndexMap.has(cell.fieldId);
122
+ const [recordId, fieldId] = cell || [];
123
+ const isVisible = visibleRowIndexMap.has(recordId) && visibleColumnIndexMap.has(fieldId);
124
+ return isVisible;
119
125
  },
120
126
  getCellIndex(aiTable, cell) {
121
127
  const visibleRowIndexMap = aiTable.context.visibleRowsIndexMap();
122
128
  const visibleColumnIndexMap = aiTable.context.visibleColumnsMap();
123
129
  if (AITable.isCellVisible(aiTable, cell)) {
130
+ const [recordId, fieldId] = cell;
124
131
  return {
125
- rowIndex: visibleRowIndexMap.get(cell.recordId),
126
- columnIndex: visibleColumnIndexMap.get(cell.fieldId)
132
+ rowIndex: visibleRowIndexMap.get(recordId),
133
+ columnIndex: visibleColumnIndexMap.get(fieldId)
127
134
  };
128
135
  }
129
136
  return null;
@@ -333,6 +340,24 @@ var AITableRowType;
333
340
  AITableRowType["record"] = "record";
334
341
  })(AITableRowType || (AITableRowType = {}));
335
342
 
343
+ var AITableFilterOperation;
344
+ (function (AITableFilterOperation) {
345
+ AITableFilterOperation["eq"] = "eq";
346
+ AITableFilterOperation["gte"] = "gte";
347
+ AITableFilterOperation["lte"] = "lte";
348
+ AITableFilterOperation["gt"] = "gt";
349
+ AITableFilterOperation["lt"] = "lt";
350
+ AITableFilterOperation["in"] = "in";
351
+ AITableFilterOperation["contain"] = "contain";
352
+ AITableFilterOperation["ne"] = "ne";
353
+ AITableFilterOperation["nin"] = "nin";
354
+ AITableFilterOperation["between"] = "between";
355
+ AITableFilterOperation["besides"] = "besides";
356
+ AITableFilterOperation["empty"] = "empty";
357
+ AITableFilterOperation["exists"] = "exists";
358
+ AITableFilterOperation["notContain"] = "not_contain";
359
+ })(AITableFilterOperation || (AITableFilterOperation = {}));
360
+
336
361
  /**
337
362
  * 用于构建 Canvas 基础坐标系,后续的绘制工作以此为基础
338
363
  */
@@ -672,11 +697,12 @@ function createAITable(records, fields) {
672
697
  records,
673
698
  fields,
674
699
  selection: signal({
675
- selectedRecords: new Map(),
676
- selectedFields: new Map(),
677
- selectedCells: new Map()
700
+ selectedRecords: new Set(),
701
+ selectedFields: new Set(),
702
+ selectedCells: new Set(),
703
+ activeCell: null
678
704
  }),
679
- matchedCells: signal([]),
705
+ keywordsMatchedCells: signal(new Set()),
680
706
  recordsMap: computed(() => {
681
707
  return records().reduce((object, item) => {
682
708
  object[item._id] = item;
@@ -1541,37 +1567,34 @@ class AITableGridSelectionService {
1541
1567
  }
1542
1568
  clearSelection() {
1543
1569
  this.aiTable.selection.set({
1544
- selectedRecords: new Map(),
1545
- selectedFields: new Map(),
1546
- selectedCells: new Map()
1570
+ selectedRecords: new Set(),
1571
+ selectedFields: new Set(),
1572
+ selectedCells: new Set(),
1573
+ activeCell: null
1547
1574
  });
1548
1575
  }
1549
- selectCell(recordId, fieldId) {
1550
- const fields = this.aiTable.selection().selectedCells.get(recordId);
1551
- if (fields?.hasOwnProperty(fieldId)) {
1552
- return;
1553
- }
1554
- this.clearSelection();
1555
- this.aiTable.selection().selectedCells.set(recordId, { [fieldId]: true });
1576
+ setActiveCell(activeCell) {
1577
+ this.aiTable.selection().activeCell = activeCell;
1556
1578
  }
1557
1579
  selectField(fieldId) {
1558
1580
  if (this.aiTable.selection().selectedFields.has(fieldId)) {
1559
1581
  return;
1560
1582
  }
1561
1583
  this.clearSelection();
1562
- this.aiTable.selection().selectedFields.set(fieldId, true);
1584
+ this.aiTable.selection().selectedFields.add(fieldId);
1563
1585
  }
1564
1586
  selectRecord(recordId) {
1565
1587
  if (this.aiTable.selection().selectedRecords.has(recordId)) {
1566
1588
  this.aiTable.selection().selectedRecords.delete(recordId);
1567
1589
  }
1568
1590
  else {
1569
- this.aiTable.selection().selectedRecords.set(recordId, true);
1591
+ this.aiTable.selection().selectedRecords.add(recordId);
1570
1592
  }
1571
1593
  this.aiTable.selection.set({
1572
1594
  selectedRecords: this.aiTable.selection().selectedRecords,
1573
- selectedFields: new Map(),
1574
- selectedCells: new Map()
1595
+ selectedFields: new Set(),
1596
+ selectedCells: new Set(),
1597
+ activeCell: null
1575
1598
  });
1576
1599
  }
1577
1600
  toggleSelectAll(checked) {
@@ -1594,7 +1617,7 @@ class AITableGridSelectionService {
1594
1617
  if (cellDom) {
1595
1618
  const fieldId = cellDom.getAttribute('fieldId');
1596
1619
  const recordId = cellDom.getAttribute('recordId');
1597
- fieldId && recordId && this.selectCell(recordId, fieldId);
1620
+ fieldId && recordId && this.selectCells([recordId, fieldId]);
1598
1621
  }
1599
1622
  if (colDom && !fieldAction) {
1600
1623
  const fieldId = colDom.getAttribute('fieldId');
@@ -1604,6 +1627,34 @@ class AITableGridSelectionService {
1604
1627
  this.clearSelection();
1605
1628
  }
1606
1629
  }
1630
+ selectCells(startCell, endCell) {
1631
+ const [startRecordId, startFieldId] = startCell;
1632
+ const records = this.aiTable.records();
1633
+ const fields = this.aiTable.fields();
1634
+ const selectedCells = new Set();
1635
+ if (!endCell) {
1636
+ selectedCells.add(`${startRecordId}:${startFieldId}`);
1637
+ }
1638
+ else {
1639
+ const [endRecordId, endFieldId] = endCell;
1640
+ const startRowIndex = records.findIndex((record) => record._id === startRecordId);
1641
+ const endRowIndex = records.findIndex((record) => record._id === endRecordId);
1642
+ const startColIndex = fields.findIndex((field) => field._id === startFieldId);
1643
+ const endColIndex = fields.findIndex((field) => field._id === endFieldId);
1644
+ const minRowIndex = Math.min(startRowIndex, endRowIndex);
1645
+ const maxRowIndex = Math.max(startRowIndex, endRowIndex);
1646
+ const minColIndex = Math.min(startColIndex, endColIndex);
1647
+ const maxColIndex = Math.max(startColIndex, endColIndex);
1648
+ for (let i = minRowIndex; i <= maxRowIndex; i++) {
1649
+ for (let j = minColIndex; j <= maxColIndex; j++) {
1650
+ selectedCells.add(`${records[i]._id}:${fields[j]._id}`);
1651
+ }
1652
+ }
1653
+ }
1654
+ this.clearSelection();
1655
+ this.setActiveCell(startCell);
1656
+ this.aiTable.selection().selectedCells = selectedCells;
1657
+ }
1607
1658
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridSelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1608
1659
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridSelectionService }); }
1609
1660
  }
@@ -1626,20 +1677,13 @@ class AITableContextMenu extends ThyDropdownAbstractMenu {
1626
1677
  }
1627
1678
  }
1628
1679
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableContextMenu, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1629
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableContextMenu, isStandalone: true, selector: "ai-table-context-menu", inputs: { aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: true, transformFunction: null }, menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: true, transformFunction: null }, targetName: { classPropertyName: "targetName", publicName: "targetName", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "context-menu" }, usesInheritance: true, ngImport: i0, template: "@for (menu of menuItems(); track $index) {\n @if ((menu.hidden && !menu.hidden(aiTable(), targetName(), position())) || !menu.hidden) {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable(), targetName(), position()));\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'ai-table-prohibit-clear-selection remove-record': !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ menu.name }}</span>\n </a>\n }\n}\n", dependencies: [{ kind: "directive", type: ThyDropdownMenuItemDirective, selector: "[thyDropdownMenuItem]", inputs: ["thyType", "thyDisabled"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1680
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableContextMenu, isStandalone: true, selector: "ai-table-context-menu", inputs: { aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: true, transformFunction: null }, menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: true, transformFunction: null }, targetName: { classPropertyName: "targetName", publicName: "targetName", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "context-menu" }, usesInheritance: true, ngImport: i0, template: "@for (menu of menuItems(); track $index) {\n @if ((menu.hidden && !menu.hidden(aiTable(), targetName(), position())) || !menu.hidden) {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable(), targetName(), position()));\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'ai-table-prevent-clear-selection remove-record': !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ menu.name }}</span>\n </a>\n }\n}\n", dependencies: [{ kind: "directive", type: ThyDropdownMenuItemDirective, selector: "[thyDropdownMenuItem]", inputs: ["thyType", "thyDisabled"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1630
1681
  }
1631
1682
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableContextMenu, decorators: [{
1632
1683
  type: Component,
1633
1684
  args: [{ selector: 'ai-table-context-menu', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
1634
1685
  class: 'context-menu'
1635
- }, imports: [
1636
- ThyDropdownMenuComponent,
1637
- ThyDropdownMenuItemDirective,
1638
- ThyDropdownMenuItemNameDirective,
1639
- ThyDropdownMenuItemIconDirective,
1640
- ThyIcon,
1641
- NgClass
1642
- ], template: "@for (menu of menuItems(); track $index) {\n @if ((menu.hidden && !menu.hidden(aiTable(), targetName(), position())) || !menu.hidden) {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable(), targetName(), position()));\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'ai-table-prohibit-clear-selection remove-record': !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ menu.name }}</span>\n </a>\n }\n}\n" }]
1686
+ }, imports: [ThyDropdownMenuItemDirective, ThyIcon, NgClass], template: "@for (menu of menuItems(); track $index) {\n @if ((menu.hidden && !menu.hidden(aiTable(), targetName(), position())) || !menu.hidden) {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable(), targetName(), position()));\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'ai-table-prevent-clear-selection remove-record': !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ menu.name }}</span>\n </a>\n }\n}\n" }]
1643
1687
  }] });
1644
1688
 
1645
1689
  const GRID_CELL_EDITOR_MAP = {
@@ -1675,7 +1719,7 @@ const AI_TABLE_FIELD_ADD_BUTTON = 'AI_TABLE_FIELD_ADD_BUTTON'; // 添加列名
1675
1719
  const AI_TABLE_FIELD_ADD_BUTTON_WIDTH = 100; // 添加列宽度
1676
1720
  const AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE = 8; // 字段表列头图标的间距
1677
1721
  const AI_TABLE_FIELD_HEAD_MORE = 'AI_TABLE_FIELD_HEAD_MORE'; // 更多图标名称
1678
- const AI_TABLE_PROHIBIT_CLEAR_SELECTION_CLASS = '.ai-table-prohibit-clear-selection';
1722
+ const AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS = '.ai-table-prevent-clear-selection';
1679
1723
  const AI_TABLE_ICON_COMMON_SIZE = 16; // 表格图标的通用尺寸
1680
1724
  const AI_TABLE_CELL = 'AI_TABLE_CELL'; // 单元格标识
1681
1725
  // 因为 dom 的边距 12 是不包含 边框的,所以加上边框 2px 才能跟 编辑里面的内容对其;
@@ -1928,47 +1972,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1928
1972
  type: Injectable
1929
1973
  }], ctorParameters: () => [{ type: i1$1.ThyPopover }] });
1930
1974
 
1931
- class AITableGridMatchCellService {
1932
- initialize(aiTable) {
1933
- this.aiTable = aiTable;
1934
- }
1935
- findMatchedCells(keywords, references) {
1936
- if (!keywords) {
1937
- this.clearMatchedCells();
1938
- return;
1939
- }
1940
- let matchedCells = [];
1941
- this.aiTable.records().forEach((record) => {
1942
- this.aiTable.fields().forEach((field) => {
1943
- if (this.isCellMatchKeywords(this.aiTable, field, record._id, keywords, references)) {
1944
- matchedCells.push(`${record._id}-${field._id}`);
1945
- }
1946
- });
1947
- });
1948
- this.aiTable.matchedCells.set([...matchedCells]);
1949
- }
1950
- clearMatchedCells() {
1951
- this.aiTable.matchedCells.set([]);
1952
- }
1953
- isCellMatchKeywords(aiTable, field, recordId, keywords, references) {
1954
- const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, field._id]);
1955
- const transformValue = transformCellValue(aiTable, field, cellValue);
1956
- const fieldMethod = ViewOperationMap[field.type];
1957
- let cellFullText = fieldMethod.cellFullText(transformValue, field, references);
1958
- try {
1959
- return keywords && cellFullText.length && cellFullText.some((item) => item.toLowerCase().includes(keywords.toLowerCase()));
1960
- }
1961
- catch (error) {
1962
- return false;
1963
- }
1964
- }
1965
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridMatchCellService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1966
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridMatchCellService }); }
1967
- }
1968
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridMatchCellService, decorators: [{
1969
- type: Injectable
1970
- }] });
1971
-
1972
1975
  function getColumnIndicesMap(fields) {
1973
1976
  const columnIndicesMap = {};
1974
1977
  fields?.forEach((field, index) => {
@@ -2480,19 +2483,195 @@ const TextMeasure = (defaults = {}) => {
2480
2483
  };
2481
2484
 
2482
2485
  class Field {
2486
+ // 筛选
2487
+ isMeetFilter(condition, cellValue) {
2488
+ switch (condition.operation) {
2489
+ case AITableFilterOperation.empty:
2490
+ case AITableFilterOperation.exists: {
2491
+ return this.isEmptyOrNot(condition.operation, cellValue);
2492
+ }
2493
+ default: {
2494
+ return true;
2495
+ }
2496
+ }
2497
+ }
2498
+ // 查找
2499
+ cellFullText(transformValue, field, references) {
2500
+ let fullText = [];
2501
+ if (!isEmpty(transformValue)) {
2502
+ fullText.push(String(transformValue));
2503
+ }
2504
+ return fullText;
2505
+ }
2506
+ isEmptyOrNot(operation, cellValue) {
2507
+ switch (operation) {
2508
+ case AITableFilterOperation.empty: {
2509
+ return isEmpty(cellValue);
2510
+ }
2511
+ case AITableFilterOperation.exists: {
2512
+ return !isEmpty(cellValue);
2513
+ }
2514
+ default: {
2515
+ throw new Error('compare operator type error');
2516
+ }
2517
+ }
2518
+ }
2519
+ }
2520
+
2521
+ const zhIntlCollator = typeof Intl !== 'undefined' ? new Intl.Collator('zh-CN') : undefined;
2522
+ function compareNumber(a, b) {
2523
+ if (isEmpty(a) && isEmpty(b)) {
2524
+ return 0;
2525
+ }
2526
+ if (isEmpty(a)) {
2527
+ return -1;
2528
+ }
2529
+ if (isEmpty(b)) {
2530
+ return 1;
2531
+ }
2532
+ return a === b ? 0 : a > b ? 1 : -1;
2533
+ }
2534
+ function compareString(a, b) {
2535
+ if (a === b) {
2536
+ return 0;
2537
+ }
2538
+ if (a == null) {
2539
+ return -1;
2540
+ }
2541
+ if (b == null) {
2542
+ return 1;
2543
+ }
2544
+ // pinyin sort
2545
+ return a === b ? 0 : zhIntlCollator ? zhIntlCollator.compare(a, b) : a.localeCompare(b, 'zh-CN') > 0 ? 1 : -1;
2546
+ }
2547
+ function stringInclude(str, searchStr) {
2548
+ return str.toLowerCase().includes(searchStr.trim().toLowerCase());
2549
+ }
2550
+ /**
2551
+ * 两数组是否有交集
2552
+ */
2553
+ function hasIntersect(array1, array2) {
2554
+ if (!Array.isArray(array1) || !Array.isArray(array2)) {
2555
+ return false;
2556
+ }
2557
+ const set1 = new Set(array1);
2558
+ const set2 = new Set(array2);
2559
+ for (const element of set1) {
2560
+ if (set2.has(element)) {
2561
+ return true;
2562
+ }
2563
+ }
2564
+ return false;
2565
+ }
2566
+
2567
+ class DateField extends Field {
2568
+ isMeetFilter(condition, cellValue) {
2569
+ const [left, right] = this.getTimeRange(condition.value);
2570
+ switch (condition.operation) {
2571
+ case AITableFilterOperation.empty:
2572
+ return isEmpty$1(cellValue.timestamp) || cellValue.timestamp === 0;
2573
+ case AITableFilterOperation.exists:
2574
+ return !isEmpty$1(cellValue.timestamp) && cellValue.timestamp !== 0;
2575
+ case AITableFilterOperation.eq:
2576
+ return left <= cellValue.timestamp && cellValue.timestamp < right;
2577
+ case AITableFilterOperation.gt:
2578
+ return cellValue.timestamp > right;
2579
+ case AITableFilterOperation.lt:
2580
+ return cellValue.timestamp < left;
2581
+ case AITableFilterOperation.between:
2582
+ return left <= cellValue.timestamp && cellValue.timestamp < right;
2583
+ default:
2584
+ return super.isMeetFilter(condition, cellValue);
2585
+ }
2586
+ }
2587
+ compare(cellValue1, cellValue2) {
2588
+ const value1 = cellValueToSortValue$4(cellValue1);
2589
+ const value2 = cellValueToSortValue$4(cellValue2);
2590
+ return compareNumber(value1, value2);
2591
+ }
2592
+ getTimeRange(value) {
2593
+ switch (value) {
2594
+ case 'today':
2595
+ return [new TinyDate(new Date()).startOfDay().getUnixTime(), new TinyDate(new Date()).endOfDay().getUnixTime()];
2596
+ case 'current_week':
2597
+ return [
2598
+ new TinyDate().startOfWeek({ weekStartsOn: 1 }).getUnixTime(),
2599
+ new TinyDate().endOfWeek({ weekStartsOn: 1 }).getUnixTime()
2600
+ ];
2601
+ case 'yesterday':
2602
+ return [
2603
+ new TinyDate(subDays(new Date(), 1)).startOfDay().getUnixTime(),
2604
+ new TinyDate(subDays(new Date(), 1)).endOfDay().getUnixTime()
2605
+ ];
2606
+ case 'current_month':
2607
+ return [new TinyDate().startOfMonth().getUnixTime(), new TinyDate().endOfMonth().getUnixTime()];
2608
+ default:
2609
+ if (isArray(value)) {
2610
+ return [
2611
+ new TinyDate(fromUnixTime(value[0])).startOfDay().getUnixTime(),
2612
+ new TinyDate(fromUnixTime(value[1])).endOfDay().getUnixTime()
2613
+ ];
2614
+ }
2615
+ return [
2616
+ new TinyDate(fromUnixTime(value)).startOfDay().getUnixTime(),
2617
+ new TinyDate(fromUnixTime(value)).endOfDay().getUnixTime()
2618
+ ];
2619
+ }
2620
+ }
2621
+ }
2622
+ function cellValueToSortValue$4(cellValue) {
2623
+ return cellValue?.timestamp;
2483
2624
  }
2484
2625
 
2485
2626
  class LinkField extends Field {
2486
- cellFullText(transformValue, field) {
2487
- let fullText = [];
2627
+ isMeetFilter(condition, cellValue) {
2628
+ const cellTextValue = cellValue?.text;
2629
+ switch (condition.operation) {
2630
+ case AITableFilterOperation.empty:
2631
+ return isEmpty(cellTextValue);
2632
+ case AITableFilterOperation.exists:
2633
+ return !isEmpty(cellTextValue);
2634
+ case AITableFilterOperation.contain:
2635
+ return !isEmpty(cellTextValue) && stringInclude(cellTextValue, condition.value);
2636
+ default:
2637
+ return super.isMeetFilter(condition, cellTextValue);
2638
+ }
2639
+ }
2640
+ compare(cellValue1, cellValue2) {
2641
+ return compareString(cellValueToSortValue$3(cellValue1), cellValueToSortValue$3(cellValue2));
2642
+ }
2643
+ cellFullText(transformValue) {
2644
+ let texts = [];
2488
2645
  if (!isEmpty(transformValue?.text)) {
2489
- fullText.push(transformValue.text);
2646
+ texts.push(transformValue.text);
2490
2647
  }
2491
- return fullText;
2648
+ return texts;
2492
2649
  }
2493
2650
  }
2651
+ function cellValueToSortValue$3(cellValue) {
2652
+ return (cellValue && cellValue.text && cellValue.text.trim()) || null;
2653
+ }
2494
2654
 
2495
2655
  class MemberField extends Field {
2656
+ isMeetFilter(condition, cellValue) {
2657
+ switch (condition.operation) {
2658
+ case AITableFilterOperation.empty:
2659
+ return isEmpty(cellValue);
2660
+ case AITableFilterOperation.exists:
2661
+ return !isEmpty(cellValue);
2662
+ case AITableFilterOperation.in:
2663
+ return Array.isArray(condition.value) && hasIntersect(cellValue, condition.value);
2664
+ case AITableFilterOperation.nin:
2665
+ return Array.isArray(condition.value) && !hasIntersect(cellValue, condition.value);
2666
+ default:
2667
+ return super.isMeetFilter(condition, cellValue);
2668
+ }
2669
+ }
2670
+ compare(cellValue1, cellValue2, field, references, sortKey) {
2671
+ const value1 = cellValueToSortValue$2(cellValue1, field, references, sortKey);
2672
+ const value2 = cellValueToSortValue$2(cellValue2, field, references, sortKey);
2673
+ return compareString(value1, value2);
2674
+ }
2496
2675
  cellFullText(transformValue, field, references) {
2497
2676
  let fullText = [];
2498
2677
  if (transformValue?.length && references) {
@@ -2509,9 +2688,78 @@ class MemberField extends Field {
2509
2688
  return fullText;
2510
2689
  }
2511
2690
  }
2691
+ function cellValueToSortValue$2(cellValue, field, references, sortKey = 'display_name') {
2692
+ let values = [];
2693
+ if (cellValue?.length && references) {
2694
+ for (let index = 0; index < cellValue.length; index++) {
2695
+ const userInfo = references?.members[cellValue[index]];
2696
+ if (!userInfo) {
2697
+ continue;
2698
+ }
2699
+ const value = userInfo[sortKey];
2700
+ if (value) {
2701
+ values.push(value);
2702
+ }
2703
+ }
2704
+ }
2705
+ return values && values.length ? values.join(', ') : null;
2706
+ }
2707
+
2708
+ class NumberField extends Field {
2709
+ isMeetFilter(condition, cellValue) {
2710
+ switch (condition.operation) {
2711
+ case AITableFilterOperation.empty:
2712
+ return isEmpty(cellValue);
2713
+ case AITableFilterOperation.exists:
2714
+ return !isEmpty(cellValue);
2715
+ case AITableFilterOperation.eq:
2716
+ return !Number.isNaN(condition.value) && cellValue != null && cellValue !== '' && condition.value === cellValue;
2717
+ case AITableFilterOperation.gte:
2718
+ return cellValue != null && cellValue !== '' && cellValue >= condition.value;
2719
+ case AITableFilterOperation.lte:
2720
+ return cellValue != null && cellValue !== '' && cellValue <= condition.value;
2721
+ case AITableFilterOperation.gt:
2722
+ return cellValue != null && cellValue !== '' && cellValue > condition.value;
2723
+ case AITableFilterOperation.lt:
2724
+ return cellValue != null && cellValue !== '' && cellValue < condition.value;
2725
+ case AITableFilterOperation.ne:
2726
+ return cellValue == null || cellValue == '' || Number.isNaN(condition.value) || cellValue !== condition.value;
2727
+ default:
2728
+ return super.isMeetFilter(condition, cellValue);
2729
+ }
2730
+ }
2731
+ compare(cellValue1, cellValue2) {
2732
+ return compareNumber(cellValue1, cellValue2);
2733
+ }
2734
+ }
2512
2735
 
2513
2736
  class ProgressField extends Field {
2514
- cellFullText(transformValue, field) {
2737
+ isMeetFilter(condition, cellValue) {
2738
+ switch (condition.operation) {
2739
+ case AITableFilterOperation.empty:
2740
+ return isEmpty(cellValue);
2741
+ case AITableFilterOperation.exists:
2742
+ return !isEmpty(cellValue);
2743
+ case AITableFilterOperation.eq:
2744
+ return !Number.isNaN(condition.value) && cellValue != null && cellValue !== '' && condition.value === cellValue;
2745
+ case AITableFilterOperation.gte:
2746
+ return cellValue != null && cellValue !== '' && cellValue >= condition.value;
2747
+ case AITableFilterOperation.lte:
2748
+ return cellValue != null && cellValue !== '' && cellValue <= condition.value;
2749
+ case AITableFilterOperation.gt:
2750
+ return cellValue != null && cellValue !== '' && cellValue > condition.value;
2751
+ case AITableFilterOperation.lt:
2752
+ return cellValue != null && cellValue !== '' && cellValue < condition.value;
2753
+ case AITableFilterOperation.ne:
2754
+ return cellValue == null || cellValue == '' || Number.isNaN(condition.value) || cellValue !== condition.value;
2755
+ default:
2756
+ return super.isMeetFilter(condition, cellValue);
2757
+ }
2758
+ }
2759
+ compare(cellValue1, cellValue2) {
2760
+ return compareNumber(cellValue1, cellValue2);
2761
+ }
2762
+ cellFullText(transformValue) {
2515
2763
  let fullText = [];
2516
2764
  if (!isEmpty(transformValue)) {
2517
2765
  fullText.push(`${transformValue}%`);
@@ -2520,40 +2768,111 @@ class ProgressField extends Field {
2520
2768
  }
2521
2769
  }
2522
2770
 
2771
+ class RateField extends Field {
2772
+ isMeetFilter(condition, cellValue) {
2773
+ switch (condition.operation) {
2774
+ case AITableFilterOperation.empty:
2775
+ return isEmpty(cellValue);
2776
+ case AITableFilterOperation.exists:
2777
+ return !isEmpty(cellValue);
2778
+ case AITableFilterOperation.in:
2779
+ const isContain = condition.value.some((item) => String(item) === String(cellValue));
2780
+ return !isEmpty(cellValue) && isContain;
2781
+ case AITableFilterOperation.nin:
2782
+ const noContain = condition.value.every((item) => String(item) !== String(cellValue));
2783
+ return isEmpty(cellValue) || noContain;
2784
+ default:
2785
+ return super.isMeetFilter(condition, cellValue);
2786
+ }
2787
+ }
2788
+ compare(cellValue1, cellValue2) {
2789
+ return compareNumber(cellValue1, cellValue2);
2790
+ }
2791
+ }
2792
+
2523
2793
  class SelectField extends Field {
2794
+ isMeetFilter(condition, cellValue) {
2795
+ switch (condition.operation) {
2796
+ case AITableFilterOperation.empty:
2797
+ return isEmpty(cellValue);
2798
+ case AITableFilterOperation.exists:
2799
+ return !isEmpty(cellValue);
2800
+ case AITableFilterOperation.in:
2801
+ return Array.isArray(condition.value) && hasIntersect(cellValue, condition.value);
2802
+ case AITableFilterOperation.nin:
2803
+ return Array.isArray(condition.value) && !hasIntersect(cellValue, condition.value);
2804
+ default:
2805
+ return super.isMeetFilter(condition, cellValue);
2806
+ }
2807
+ }
2808
+ compare(cellValue1, cellValue2, field) {
2809
+ const value1 = cellValueToSortValue$1(cellValue1, field);
2810
+ const value2 = cellValueToSortValue$1(cellValue2, field);
2811
+ return compareString(value1, value2);
2812
+ }
2524
2813
  cellFullText(transformValue, field) {
2525
- let cellText = [];
2814
+ let fullText = [];
2815
+ const optionsMap = helpers.keyBy(field.settings.options || [], '_id');
2526
2816
  if (transformValue && Array.isArray(transformValue) && transformValue.length) {
2527
2817
  transformValue.forEach((optionId) => {
2528
- const item = field.settings?.options?.find((option) => option._id === optionId);
2529
- if (item?.text) {
2530
- cellText.push(item.text);
2818
+ const option = optionsMap[optionId];
2819
+ if (option && option.text) {
2820
+ fullText.push(option.text);
2531
2821
  }
2532
2822
  });
2533
2823
  }
2534
- return cellText;
2824
+ return fullText;
2535
2825
  }
2536
2826
  }
2827
+ function cellValueToSortValue$1(cellValue, field) {
2828
+ if (!cellValue) {
2829
+ return null;
2830
+ }
2831
+ const texts = [];
2832
+ const optionsMap = helpers.keyBy(field.settings.options || [], '_id');
2833
+ if (cellValue && Array.isArray(cellValue) && cellValue.length) {
2834
+ cellValue.forEach((optionId) => {
2835
+ const option = optionsMap[optionId];
2836
+ if (option && option.text) {
2837
+ texts.push(option.text);
2838
+ }
2839
+ });
2840
+ }
2841
+ return texts && texts.length ? texts.join(',') : null;
2842
+ }
2537
2843
 
2538
2844
  class TextField extends Field {
2539
- cellFullText(transformValue, field, references) {
2540
- let fullText = [];
2541
- if (!isEmpty(transformValue)) {
2542
- fullText.push(String(transformValue));
2845
+ isMeetFilter(condition, cellValue) {
2846
+ switch (condition.operation) {
2847
+ case AITableFilterOperation.empty:
2848
+ return isEmpty(cellValue);
2849
+ case AITableFilterOperation.exists:
2850
+ return !isEmpty(cellValue);
2851
+ case AITableFilterOperation.contain:
2852
+ return !isEmpty(cellValue) && stringInclude(cellValue, condition.value);
2853
+ default:
2854
+ return super.isMeetFilter(condition, cellValue);
2543
2855
  }
2544
- return fullText;
2545
2856
  }
2857
+ compare(cellValue1, cellValue2) {
2858
+ const value1 = cellValueToSortValue(cellValue1);
2859
+ const value2 = cellValueToSortValue(cellValue2);
2860
+ return compareString(value1, value2);
2861
+ }
2862
+ }
2863
+ function cellValueToSortValue(cellValue) {
2864
+ return (cellValue && cellValue.trim()) || null;
2546
2865
  }
2547
2866
 
2548
2867
  const ViewOperationMap = {
2549
2868
  [AITableFieldType.text]: new TextField(),
2550
2869
  [AITableFieldType.richText]: new TextField(),
2551
2870
  [AITableFieldType.select]: new SelectField(),
2552
- [AITableFieldType.date]: new TextField(),
2553
- [AITableFieldType.createdAt]: new TextField(),
2554
- [AITableFieldType.updatedAt]: new TextField(),
2555
- [AITableFieldType.number]: new TextField(),
2556
- [AITableFieldType.rate]: new TextField(),
2871
+ [AITableFieldType.date]: new DateField(),
2872
+ [AITableFieldType.createdAt]: new DateField(),
2873
+ [AITableFieldType.updatedAt]: new DateField(),
2874
+ [AITableFieldType.number]: new NumberField(),
2875
+ [AITableFieldType.rate]: new RateField(),
2557
2876
  [AITableFieldType.link]: new LinkField(),
2558
2877
  [AITableFieldType.member]: new MemberField(),
2559
2878
  [AITableFieldType.progress]: new ProgressField(),
@@ -2561,6 +2880,14 @@ const ViewOperationMap = {
2561
2880
  [AITableFieldType.updatedBy]: new MemberField()
2562
2881
  };
2563
2882
 
2883
+ const isCellMatchKeywords = (aiTable, field, recordId, keywords, references) => {
2884
+ const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, field._id]);
2885
+ const transformValue = transformCellValue(aiTable, field, cellValue);
2886
+ const fieldMethod = ViewOperationMap[field.type];
2887
+ let cellFullText = fieldMethod.cellFullText(transformValue, field, references);
2888
+ return keywords && cellFullText.length && cellFullText.some((text) => text.toLowerCase().includes(keywords.toLowerCase()));
2889
+ };
2890
+
2564
2891
  class AITableGridEventService {
2565
2892
  constructor() {
2566
2893
  this.dblClickEvent$ = new Subject();
@@ -2645,7 +2972,8 @@ class AITableGridEventService {
2645
2972
  const { container, coordinate, recordId, fieldId, isHoverEdit } = options;
2646
2973
  const { scrollState } = aiTable.context;
2647
2974
  const { rowHeight, columnCount } = coordinate;
2648
- const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, { recordId, fieldId });
2975
+ const cell = [recordId, fieldId];
2976
+ const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, cell);
2649
2977
  const originX = coordinate.getColumnOffset(columnIndex);
2650
2978
  const originY = coordinate.getRowOffset(rowIndex);
2651
2979
  const columnWidth = coordinate.getColumnWidth(columnIndex);
@@ -2814,7 +3142,6 @@ class AITableGridBase {
2814
3142
  this.aiTableGridFieldService = inject(AITableGridFieldService);
2815
3143
  this.aiTableGridEventService = inject(AITableGridEventService);
2816
3144
  this.aiTableGridSelectionService = inject(AITableGridSelectionService);
2817
- this.aiTableGridMatchCellService = inject(AITableGridMatchCellService);
2818
3145
  }
2819
3146
  ngOnInit() {
2820
3147
  this.initAITable();
@@ -2830,7 +3157,6 @@ class AITableGridBase {
2830
3157
  initService() {
2831
3158
  this.aiTableGridEventService.initialize(this.aiTable, this.aiFieldConfig()?.fieldRenderers);
2832
3159
  this.aiTableGridSelectionService.initialize(this.aiTable);
2833
- this.aiTableGridMatchCellService.initialize(this.aiTable);
2834
3160
  this.aiTableGridEventService.registerEvents(this.elementRef.nativeElement);
2835
3161
  this.aiTableGridFieldService.initAIFieldConfig(this.aiFieldConfig());
2836
3162
  this.aiTable.references.set(this.aiReferences());
@@ -2940,7 +3266,7 @@ class AITableDomGrid extends AITableGridBase {
2940
3266
  });
2941
3267
  }
2942
3268
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2943
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableDomGrid, isStandalone: true, selector: "ai-table-dom-grid", host: { classAttribute: "ai-table-grid ai-table-dom-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], 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: field.width + '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)=\"selectRecord(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 <div\n #cell\n class=\"grid-cell\"\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 [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + '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"] }, { 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 }); }
3269
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableDomGrid, isStandalone: true, selector: "ai-table-dom-grid", host: { classAttribute: "ai-table-grid ai-table-dom-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], 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: field.width + '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)=\"selectRecord(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: field.width + '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"] }, { 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 }); }
2944
3270
  }
2945
3271
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, decorators: [{
2946
3272
  type: Component,
@@ -2976,7 +3302,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2976
3302
  UserPipe,
2977
3303
  SelectSettingPipe,
2978
3304
  MemberSettingPipe
2979
- ], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], 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: field.width + '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)=\"selectRecord(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 <div\n #cell\n class=\"grid-cell\"\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 [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + '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" }]
3305
+ ], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], 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: field.width + '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)=\"selectRecord(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: field.width + '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" }]
2980
3306
  }] });
2981
3307
 
2982
3308
  const KO_CONTAINER_TOKEN = new InjectionToken('KO_CONTAINER_TOKEN');
@@ -5391,28 +5717,9 @@ const createCells = (config) => {
5391
5717
  break;
5392
5718
  }
5393
5719
  case AITableRowType.record: {
5394
- let background = colors.white;
5395
5720
  const fieldId = field._id;
5396
- const isCheckedRow = aiTable.selection().selectedRecords.has(row._id);
5397
- const isSelected = aiTable.selection().selectedFields.has(fieldId);
5398
- const isHoverRow = isHover && targetName !== AI_TABLE_FIELD_HEAD;
5399
- const activeCell = AITable.getActiveCell(aiTable);
5400
- const isSiblingActiveCell = recordId === activeCell?.recordId && fieldId !== activeCell?.fieldId;
5401
- const isActiveCell = recordId === activeCell?.recordId;
5402
- let matchedCellsMap = {};
5403
- aiTable.matchedCells().forEach((key) => {
5404
- matchedCellsMap[key] = true;
5405
- });
5406
- const isMatchedCell = matchedCellsMap[`${recordId}-${fieldId}`];
5407
- if (isMatchedCell) {
5408
- background = colors.itemMatchBgColor;
5409
- }
5410
- else if (isCheckedRow || isSelected || isSiblingActiveCell) {
5411
- background = colors.itemActiveBgColor;
5412
- }
5413
- else if (isHoverRow && !isActiveCell) {
5414
- background = colors.gray80;
5415
- }
5721
+ const cell = [recordId, fieldId];
5722
+ let background = getCellBackground(cell, isHover, targetName, aiTable);
5416
5723
  recordRowLayout.init({
5417
5724
  x,
5418
5725
  y,
@@ -5426,8 +5733,8 @@ const createCells = (config) => {
5426
5733
  recordRowLayout.render({
5427
5734
  row,
5428
5735
  style: { fill: background },
5429
- isHoverRow,
5430
- isCheckedRow
5736
+ isHoverRow: isHoverRecord(isHover, targetName),
5737
+ isCheckedRow: isSelectedRecord(recordId, aiTable)
5431
5738
  });
5432
5739
  const { width, offset } = getCellHorizontalPosition({
5433
5740
  columnIndex,
@@ -5450,7 +5757,7 @@ const createCells = (config) => {
5450
5757
  cellValue,
5451
5758
  transformValue,
5452
5759
  references,
5453
- isActive: isSelected,
5760
+ isActive: isSelectedField(fieldId, aiTable),
5454
5761
  style,
5455
5762
  colors
5456
5763
  };
@@ -5472,6 +5779,55 @@ const createCells = (config) => {
5472
5779
  }
5473
5780
  }
5474
5781
  };
5782
+ const getCellBackground = (cell, isHover, targetName, aiTable) => {
5783
+ const colors = AITable.getColors();
5784
+ const [recordId, fieldId] = cell;
5785
+ let background = colors.white;
5786
+ const _isHoverRecord = isHoverRecord(isHover, targetName);
5787
+ const _isSelectedRecord = isSelectedRecord(recordId, aiTable);
5788
+ const _isSelectedField = isSelectedField(fieldId, aiTable);
5789
+ const _isSiblingCell = isSiblingCell(cell, aiTable);
5790
+ const _isActiveCell = isActiveCell(cell, aiTable);
5791
+ const _isSelectedCell = isSelectedCell(cell, aiTable);
5792
+ const _isKeywordsMatchedCell = isKeywordsMatchedCell(cell, aiTable);
5793
+ if (_isKeywordsMatchedCell) {
5794
+ background = colors.itemMatchBgColor;
5795
+ }
5796
+ else if (_isSelectedRecord || _isSelectedField || _isSiblingCell || (_isSelectedCell && !_isActiveCell)) {
5797
+ background = colors.itemActiveBgColor;
5798
+ }
5799
+ else if (_isHoverRecord && !_isActiveCell) {
5800
+ background = colors.gray80;
5801
+ }
5802
+ return background;
5803
+ };
5804
+ const isActiveCell = (cell, aiTable) => {
5805
+ const [recordId, fieldId] = cell;
5806
+ const [activeRecordId, activeFieldId] = AITable.getActiveCell(aiTable) || [];
5807
+ return recordId === activeRecordId && fieldId === activeFieldId;
5808
+ };
5809
+ const isSiblingCell = (cell, aiTable) => {
5810
+ const [recordId, fieldId] = cell;
5811
+ const [activeRecordId, activeFieldId] = AITable.getActiveCell(aiTable) || [];
5812
+ return AITable.getActiveRecordIds(aiTable).length === 1 && recordId === activeRecordId && fieldId !== activeFieldId;
5813
+ };
5814
+ const isKeywordsMatchedCell = (cell, aiTable) => {
5815
+ const [recordId, fieldId] = cell;
5816
+ return aiTable.keywordsMatchedCells().has(`${recordId}:${fieldId}`);
5817
+ };
5818
+ const isSelectedCell = (cell, aiTable) => {
5819
+ const [recordId, fieldId] = cell;
5820
+ return aiTable.selection().selectedCells.has(`${recordId}:${fieldId}`);
5821
+ };
5822
+ const isSelectedField = (fieldId, aiTable) => {
5823
+ return aiTable.selection().selectedFields.has(fieldId);
5824
+ };
5825
+ const isSelectedRecord = (recordId, aiTable) => {
5826
+ return aiTable.selection().selectedRecords.has(recordId);
5827
+ };
5828
+ const isHoverRecord = (isHover, targetName) => {
5829
+ return isHover && targetName !== AI_TABLE_FIELD_HEAD;
5830
+ };
5475
5831
 
5476
5832
  class AITableCells {
5477
5833
  constructor() {
@@ -6183,8 +6539,11 @@ const createActiveCellBorder = (config) => {
6183
6539
  const totalColumnCount = visibleColumns.length;
6184
6540
  let activeCellBorder = null;
6185
6541
  let frozenActiveCellBorder = null;
6186
- if (activeCell != null) {
6187
- const { fieldId } = activeCell;
6542
+ if (Array.isArray(activeCell) &&
6543
+ !!activeCell.length &&
6544
+ aiTable.context.visibleRowsIndexMap().has(activeCell[0]) &&
6545
+ aiTable.context.visibleColumnsMap().has(activeCell[1])) {
6546
+ const fieldId = activeCell[1];
6188
6547
  const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, activeCell);
6189
6548
  const checkIsVisible = (rowIndex, columnIndex) => {
6190
6549
  if (columnIndex < frozenColumnCount) {
@@ -6243,6 +6602,7 @@ class AITableRenderer {
6243
6602
  this.config = input.required();
6244
6603
  this.koMousemove = output();
6245
6604
  this.koMousedown = output();
6605
+ this.koMouseup = output();
6246
6606
  this.koContextmenu = output();
6247
6607
  this.koWheel = output();
6248
6608
  this.koClick = output();
@@ -6377,6 +6737,9 @@ class AITableRenderer {
6377
6737
  stageMousedown(e) {
6378
6738
  this.koMousedown.emit(e);
6379
6739
  }
6740
+ stageMouseup(e) {
6741
+ this.koMouseup.emit(e);
6742
+ }
6380
6743
  stageContextmenu(e) {
6381
6744
  this.koContextmenu.emit(e);
6382
6745
  }
@@ -6387,7 +6750,7 @@ class AITableRenderer {
6387
6750
  this.koDblclick.emit(e);
6388
6751
  }
6389
6752
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6390
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", 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", koContextmenu: "koContextmenu", koWheel: "koWheel", koClick: "koClick", koDblclick: "koDblclick" }, ngImport: i0, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($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 <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\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]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\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 </ko-group>\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: 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6753
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", 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" }, 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>\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 <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\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]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\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 </ko-group>\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: 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6391
6754
  }
6392
6755
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableRenderer, decorators: [{
6393
6756
  type: Component,
@@ -6404,13 +6767,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
6404
6767
  AITableAddField,
6405
6768
  AITableHoverRowHeads,
6406
6769
  AITableOtherRows
6407
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($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 <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\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]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\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 </ko-group>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n" }]
6770
+ ], 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>\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 <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\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]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\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 </ko-group>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n" }]
6408
6771
  }] });
6409
6772
 
6410
6773
  class AITableGrid extends AITableGridBase {
6411
6774
  constructor() {
6412
6775
  super();
6413
6776
  this.viewContainerRef = inject(ViewContainerRef);
6777
+ this.isDragSelecting = false;
6778
+ this.dragSelectionStart = null;
6414
6779
  this.fieldHeadHeight = AI_TABLE_FIELD_HEAD_HEIGHT;
6415
6780
  this.containerRect = signal({ width: 0, height: 0 });
6416
6781
  this.hasContainerRect = computed(() => {
@@ -6514,7 +6879,7 @@ class AITableGrid extends AITableGridBase {
6514
6879
  }
6515
6880
  });
6516
6881
  effect(() => {
6517
- this.aiTableGridMatchCellService.findMatchedCells(this.aiKeywords(), this.aiReferences());
6882
+ this.setKeywordsMatchedCells();
6518
6883
  }, { allowSignalWrites: true });
6519
6884
  }
6520
6885
  ngOnInit() {
@@ -6534,6 +6899,21 @@ class AITableGrid extends AITableGridBase {
6534
6899
  scrollAction: this.scrollAction
6535
6900
  });
6536
6901
  }
6902
+ setKeywordsMatchedCells() {
6903
+ const keywords = this.aiKeywords();
6904
+ let matchedCells = new Set();
6905
+ if (keywords) {
6906
+ const references = this.aiReferences();
6907
+ this.aiTable.records().forEach((record) => {
6908
+ this.aiTable.fields().forEach((field) => {
6909
+ if (isCellMatchKeywords(this.aiTable, field, record._id, keywords, references)) {
6910
+ matchedCells.add(`${record._id}:${field._id}`);
6911
+ }
6912
+ });
6913
+ });
6914
+ }
6915
+ this.aiTable.keywordsMatchedCells.set(matchedCells);
6916
+ }
6537
6917
  stageMousemove(e) {
6538
6918
  if (this.timer) {
6539
6919
  cancelAnimationFrame(this.timer);
@@ -6550,6 +6930,16 @@ class AITableGrid extends AITableGridBase {
6550
6930
  handleMouseStyle(curMousePosition.realTargetName, curMousePosition.areaType, this.containerElement());
6551
6931
  context.setPointPosition(curMousePosition);
6552
6932
  this.timer = null;
6933
+ if (this.isDragSelecting) {
6934
+ const { fieldId, recordId } = getDetailByTargetName(curMousePosition.realTargetName);
6935
+ if (fieldId && recordId) {
6936
+ const startCell = this.dragSelectionStart;
6937
+ const endCell = [recordId, fieldId];
6938
+ if (startCell && !!startCell.length) {
6939
+ this.aiTableGridSelectionService.selectCells(startCell, endCell);
6940
+ }
6941
+ }
6942
+ }
6553
6943
  });
6554
6944
  }
6555
6945
  stageMousedown(e) {
@@ -6559,7 +6949,7 @@ class AITableGrid extends AITableGridBase {
6559
6949
  if (mouseEvent.button === AITableMouseDownType.Right &&
6560
6950
  recordId &&
6561
6951
  fieldId &&
6562
- this.aiTable.selection().selectedRecords.has(recordId)) {
6952
+ (this.aiTable.selection().selectedRecords.has(recordId) || this.aiTable.selection().selectedCells.has(`${recordId}:${fieldId}`))) {
6563
6953
  return;
6564
6954
  }
6565
6955
  switch (targetName) {
@@ -6573,7 +6963,9 @@ class AITableGrid extends AITableGridBase {
6573
6963
  if (!recordId || !fieldId)
6574
6964
  return;
6575
6965
  this.aiTableGridEventService.closeCellEditor();
6576
- this.aiTableGridSelectionService.selectCell(recordId, fieldId);
6966
+ const dragSelectionStart = [recordId, fieldId];
6967
+ this.updateDragSelectionState(true, dragSelectionStart);
6968
+ this.aiTableGridSelectionService.selectCells(dragSelectionStart);
6577
6969
  return;
6578
6970
  case AI_TABLE_ROW_ADD_BUTTON:
6579
6971
  case AI_TABLE_FIELD_ADD_BUTTON:
@@ -6584,6 +6976,9 @@ class AITableGrid extends AITableGridBase {
6584
6976
  this.aiTableGridSelectionService.clearSelection();
6585
6977
  }
6586
6978
  }
6979
+ stageMouseup(e) {
6980
+ this.updateDragSelectionState(false, null);
6981
+ }
6587
6982
  stageContextmenu(e) {
6588
6983
  const mouseEvent = e.event.evt;
6589
6984
  mouseEvent.preventDefault();
@@ -6725,11 +7120,16 @@ class AITableGrid extends AITableGridBase {
6725
7120
  fromEvent(document, 'mousedown', { passive: true })
6726
7121
  .pipe(filter((e) => e.target instanceof Element &&
6727
7122
  !this.containerElement().contains(e.target) &&
6728
- !(e.target.closest(AI_TABLE_PROHIBIT_CLEAR_SELECTION_CLASS) && this.aiTable.selection().selectedRecords.size > 0)), takeUntilDestroyed(this.destroyRef))
7123
+ !e.target.closest(AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS)), takeUntilDestroyed(this.destroyRef))
6729
7124
  .subscribe(() => {
7125
+ this.updateDragSelectionState(false, null);
6730
7126
  this.aiTableGridSelectionService.clearSelection();
6731
7127
  });
6732
7128
  }
7129
+ updateDragSelectionState(isDragSelecting, dragSelectionStart) {
7130
+ this.isDragSelecting = isDragSelecting;
7131
+ this.dragSelectionStart = dragSelectionStart;
7132
+ }
6733
7133
  verticalScroll(e) {
6734
7134
  const { scrollTop } = e.target;
6735
7135
  this.aiTable.context.setScrollState({
@@ -6801,18 +7201,18 @@ class AITableGrid extends AITableGridBase {
6801
7201
  }
6802
7202
  }
6803
7203
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGrid, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6804
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableGrid, isStandalone: true, selector: "ai-table-grid", host: { classAttribute: "ai-table-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService, AITableGridMatchCellService], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "verticalBarRef", first: true, predicate: ["verticalBar"], descendants: true, isSignal: true }, { propertyName: "horizontalBarRef", first: true, predicate: ["horizontalBar"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div #container class=\"ai-table-grid-view\">\n @if (hasContainerRect()) {\n <ai-table-renderer\n [config]=\"rendererConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n >\n <div #horizontalBar class=\"ai-table-horizontal-scroll-bar-wrapper\" [style.width.px]=\"containerRect().width\">\n <div class=\"ai-table-scroll-bar-inner\" [style.width.px]=\"scrollbarWidth()\"></div>\n </div>\n <div\n #verticalBar\n class=\"ai-table-vertical-scroll-bar-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n <div class=\"ai-table-scroll-bar-inner\" [style.height.px]=\"scrollTotalHeight()\"></div>\n </div>\n </ai-table-renderer>\n }\n</div>\n", dependencies: [{ kind: "component", type: AITableRenderer, selector: "ai-table-renderer", inputs: ["config"], outputs: ["koMousemove", "koMousedown", "koContextmenu", "koWheel", "koClick", "koDblclick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7204
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableGrid, isStandalone: true, selector: "ai-table-grid", host: { classAttribute: "ai-table-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "verticalBarRef", first: true, predicate: ["verticalBar"], descendants: true, isSignal: true }, { propertyName: "horizontalBarRef", first: true, predicate: ["horizontalBar"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div #container class=\"ai-table-grid-view\">\n @if (hasContainerRect()) {\n <ai-table-renderer\n [config]=\"rendererConfig()\"\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 >\n <div #horizontalBar class=\"ai-table-horizontal-scroll-bar-wrapper\" [style.width.px]=\"containerRect().width\">\n <div class=\"ai-table-scroll-bar-inner\" [style.width.px]=\"scrollbarWidth()\"></div>\n </div>\n <div\n #verticalBar\n class=\"ai-table-vertical-scroll-bar-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n <div class=\"ai-table-scroll-bar-inner\" [style.height.px]=\"scrollTotalHeight()\"></div>\n </div>\n </ai-table-renderer>\n }\n</div>\n", dependencies: [{ kind: "component", type: AITableRenderer, selector: "ai-table-renderer", inputs: ["config"], outputs: ["koMousemove", "koMousedown", "koMouseup", "koContextmenu", "koWheel", "koClick", "koDblclick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6805
7205
  }
6806
7206
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGrid, decorators: [{
6807
7207
  type: Component,
6808
7208
  args: [{ selector: 'ai-table-grid', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
6809
7209
  class: 'ai-table-grid'
6810
- }, imports: [AITableRenderer], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService, AITableGridMatchCellService], template: "<div #container class=\"ai-table-grid-view\">\n @if (hasContainerRect()) {\n <ai-table-renderer\n [config]=\"rendererConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n >\n <div #horizontalBar class=\"ai-table-horizontal-scroll-bar-wrapper\" [style.width.px]=\"containerRect().width\">\n <div class=\"ai-table-scroll-bar-inner\" [style.width.px]=\"scrollbarWidth()\"></div>\n </div>\n <div\n #verticalBar\n class=\"ai-table-vertical-scroll-bar-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n <div class=\"ai-table-scroll-bar-inner\" [style.height.px]=\"scrollTotalHeight()\"></div>\n </div>\n </ai-table-renderer>\n }\n</div>\n" }]
7210
+ }, imports: [AITableRenderer], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div #container class=\"ai-table-grid-view\">\n @if (hasContainerRect()) {\n <ai-table-renderer\n [config]=\"rendererConfig()\"\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 >\n <div #horizontalBar class=\"ai-table-horizontal-scroll-bar-wrapper\" [style.width.px]=\"containerRect().width\">\n <div class=\"ai-table-scroll-bar-inner\" [style.width.px]=\"scrollbarWidth()\"></div>\n </div>\n <div\n #verticalBar\n class=\"ai-table-vertical-scroll-bar-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n <div class=\"ai-table-scroll-bar-inner\" [style.height.px]=\"scrollTotalHeight()\"></div>\n </div>\n </ai-table-renderer>\n }\n</div>\n" }]
6811
7211
  }], ctorParameters: () => [] });
6812
7212
 
6813
7213
  /**
6814
7214
  * Generated bundle index. Do not edit.
6815
7215
  */
6816
7216
 
6817
- export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsMultiplePipe, AITableFieldPropertyEditor, AITableFieldType, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridMatchCellService, AITableGridSelectionService, AITableMemberType, AITableMouseDownType, AITableQueries, AITableRenderer, AITableRowColumnType, AITableRowType, AITableSelectOptionStyle, AITableStatType, AI_TABLE_ACTION_COMMON_SIZE, AI_TABLE_BLANK, AI_TABLE_CELL, AI_TABLE_CELL_ACTIVE_BORDER_WIDTH, AI_TABLE_CELL_ADD_ITEM_BUTTON_SIZE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, 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_SELECT_CHECKBOX, AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH, AI_TABLE_GRID_FIELD_SERVICE_MAP, AI_TABLE_ICON_COMMON_SIZE, 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_PIECE_RADIUS, AI_TABLE_PIECE_WIDTH, AI_TABLE_POPOVER_LEFT_OFFSET, AI_TABLE_PROGRESS_BAR_HEIGHT, AI_TABLE_PROGRESS_BAR_RADIUS, AI_TABLE_PROGRESS_TEXT_Width, AI_TABLE_PROHIBIT_CLEAR_SELECTION_CLASS, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_HEIGHT, AI_TABLE_ROW_SELECT_CHECKBOX, AI_TABLE_SCROLL_BAR_PADDING, AI_TABLE_TAG_FONT_SIZE, AI_TABLE_TAG_PADDING, AI_TABLE_TEXT_GAP, AbstractEditCellEditor, AddOutlinedPath, Check, Colors, ColumnCalendarFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnSelectFilledPath, ColumnTextFilledPath, Coordinate, 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, DepartmentOutlinedPath, Direction, FONT_SIZE_SM, FieldOptions, GRID_CELL_EDITOR_MAP, IsSelectRecordPipe, LinkCellEditorComponent, MIN_COLUMN_WIDTH, MOUSEOVER_EDIT_TYPE, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, ProgressEditorComponent, RatingCellEditorComponent, RendererContext, RowHeight, SelectCellEditorComponent, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextMeasure, Unchecked, UserPipe, ViewOperationMap, WebOutlinedPath, buildGridData, buildGridLinearRows, castToString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesMap, getDefaultFieldValue, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getHoverEditorBoxOffset, getHoverEditorSpace, getMousePosition, getPlaceHolderCellsConfigs, getTargetName, getTextWidth, getVisibleRangeInfo, handleMouseStyle, idCreator, idsCreator, imageCache, isArrayField, isEmpty, isMac, isNumberFiled, isSameFieldOption, isSystemField, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, scrollMax, setMouseStyle, shortIdCreator, shortIdsCreator, textDataCache, transformCellValue };
7217
+ export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsMultiplePipe, AITableFieldPropertyEditor, AITableFieldType, AITableFilterOperation, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridSelectionService, AITableMemberType, AITableMouseDownType, AITableQueries, AITableRenderer, AITableRowColumnType, AITableRowType, AITableSelectOptionStyle, AITableStatType, AI_TABLE_ACTION_COMMON_SIZE, AI_TABLE_BLANK, AI_TABLE_CELL, AI_TABLE_CELL_ACTIVE_BORDER_WIDTH, AI_TABLE_CELL_ADD_ITEM_BUTTON_SIZE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, 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_SELECT_CHECKBOX, AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH, AI_TABLE_GRID_FIELD_SERVICE_MAP, AI_TABLE_ICON_COMMON_SIZE, 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_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_RADIUS, AI_TABLE_PROGRESS_TEXT_Width, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_HEIGHT, AI_TABLE_ROW_SELECT_CHECKBOX, AI_TABLE_SCROLL_BAR_PADDING, AI_TABLE_TAG_FONT_SIZE, AI_TABLE_TAG_PADDING, AI_TABLE_TEXT_GAP, AbstractEditCellEditor, AddOutlinedPath, Check, Colors, ColumnCalendarFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnSelectFilledPath, ColumnTextFilledPath, Coordinate, 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, DepartmentOutlinedPath, Direction, FONT_SIZE_SM, FieldOptions, GRID_CELL_EDITOR_MAP, IsSelectRecordPipe, LinkCellEditorComponent, MIN_COLUMN_WIDTH, MOUSEOVER_EDIT_TYPE, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, ProgressEditorComponent, RatingCellEditorComponent, RendererContext, RowHeight, SelectCellEditorComponent, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextMeasure, Unchecked, UserPipe, ViewOperationMap, WebOutlinedPath, buildGridData, buildGridLinearRows, castToString, compareNumber, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesMap, getDefaultFieldValue, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getHoverEditorBoxOffset, getHoverEditorSpace, getMousePosition, getPlaceHolderCellsConfigs, getTargetName, getTextWidth, getVisibleRangeInfo, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isArrayField, isCellMatchKeywords, isEmpty, isMac, isNumberFiled, isSameFieldOption, isSystemField, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, scrollMax, setMouseStyle, shortIdCreator, shortIdsCreator, stringInclude, textDataCache, transformCellValue, zhIntlCollator };
6818
7218
  //# sourceMappingURL=ai-table-grid.mjs.map