@ai-table/grid 0.0.43 → 0.0.44

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 (57) hide show
  1. package/angular-konva/interfaces/event-object.d.ts +4 -0
  2. package/angular-konva/interfaces/event-object.d.ts.map +1 -1
  3. package/components/field-menu/field-menu.component.d.ts +3 -2
  4. package/components/field-menu/field-menu.component.d.ts.map +1 -1
  5. package/constants/grid.d.ts.map +1 -1
  6. package/constants/table.d.ts +5 -1
  7. package/constants/table.d.ts.map +1 -1
  8. package/esm2022/angular-konva/interfaces/event-object.mjs +1 -1
  9. package/esm2022/components/field-menu/field-menu.component.mjs +9 -3
  10. package/esm2022/constants/grid.mjs +1 -2
  11. package/esm2022/constants/table.mjs +6 -2
  12. package/esm2022/grid-base.component.mjs +4 -2
  13. package/esm2022/grid.component.mjs +38 -22
  14. package/esm2022/renderer/components/action-icon.component.mjs +117 -0
  15. package/esm2022/renderer/components/cells/attachment.component.mjs +117 -0
  16. package/esm2022/renderer/components/cells/index.mjs +3 -1
  17. package/esm2022/renderer/components/hover-cell.component.mjs +7 -7
  18. package/esm2022/renderer/drawers/cell-drawer.mjs +4 -7
  19. package/esm2022/types/cell.mjs +1 -1
  20. package/esm2022/types/component-config.mjs +1 -1
  21. package/esm2022/types/field.mjs +1 -1
  22. package/esm2022/utils/clipboard/paste.mjs +3 -2
  23. package/esm2022/utils/common.mjs +6 -5
  24. package/esm2022/utils/field/model/date.mjs +6 -12
  25. package/esm2022/utils/field/model/progress.mjs +11 -4
  26. package/esm2022/utils/file.mjs +1 -93
  27. package/esm2022/utils/hover-cell.mjs +1 -8
  28. package/fesm2022/ai-table-grid.mjs +1322 -1252
  29. package/fesm2022/ai-table-grid.mjs.map +1 -1
  30. package/grid-base.component.d.ts +4 -1
  31. package/grid-base.component.d.ts.map +1 -1
  32. package/grid.component.d.ts.map +1 -1
  33. package/package.json +1 -1
  34. package/renderer/components/action-icon.component.d.ts +47 -0
  35. package/renderer/components/action-icon.component.d.ts.map +1 -0
  36. package/renderer/components/cells/attachment.component.d.ts +16 -0
  37. package/renderer/components/cells/attachment.component.d.ts.map +1 -0
  38. package/renderer/components/cells/index.d.ts +1 -0
  39. package/renderer/components/cells/index.d.ts.map +1 -1
  40. package/renderer/drawers/cell-drawer.d.ts.map +1 -1
  41. package/types/cell.d.ts +1 -0
  42. package/types/cell.d.ts.map +1 -1
  43. package/types/component-config.d.ts +13 -1
  44. package/types/component-config.d.ts.map +1 -1
  45. package/types/field.d.ts +1 -1
  46. package/types/field.d.ts.map +1 -1
  47. package/utils/clipboard/paste.d.ts.map +1 -1
  48. package/utils/common.d.ts +1 -1
  49. package/utils/common.d.ts.map +1 -1
  50. package/utils/field/model/date.d.ts.map +1 -1
  51. package/utils/field/model/progress.d.ts.map +1 -1
  52. package/utils/file.d.ts +0 -9
  53. package/utils/file.d.ts.map +1 -1
  54. package/utils/hover-cell.d.ts.map +1 -1
  55. package/esm2022/utils/icon.mjs +0 -48
  56. package/utils/icon.d.ts +0 -19
  57. package/utils/icon.d.ts.map +0 -1
@@ -1813,6 +1813,8 @@ const GRID_CELL_EDITOR_MAP = {
1813
1813
  };
1814
1814
 
1815
1815
  const AI_TABLE_ACTION_COMMON_SIZE = 32; // 表格图标action背景的通用尺寸
1816
+ const AI_TABLE_ACTION_COMMON_RADIUS = 4; // 表格图标action背景的radius通用尺寸
1817
+ const AI_TABLE_ACTION_COMMON_RIGHT_PADDING = 6; // 表格图标action右侧padding尺寸
1816
1818
  const AI_TABLE_DEFAULT_COLUMN_WIDTH = 200; // 默认列宽
1817
1819
  const AI_TABLE_SCROLL_BAR_PADDING = 3; // 单元格滑动容器的滚动条宽度
1818
1820
  const AI_TABLE_OFFSET = 0.5; // 边框线偏移值
@@ -1827,6 +1829,8 @@ const AI_TABLE_FIELD_HEAD_HEIGHT = 44; // 表格字段列头的高度
1827
1829
  const AI_TABLE_ROW_BLANK_HEIGHT = 43; // 减去边框后真实的行高
1828
1830
  const AI_TABLE_ROW_HEIGHT = 44; // 默认行高基准
1829
1831
  const AI_TABLE_CELL_ACTIVE_BORDER_WIDTH = 2; // 选中单元格的边框宽度
1832
+ const AI_TABLE_CELL_ATTACHMENT_ADD = 'AI_TABLE_CELL_ATTACHMENT_ADD'; // 附件cell中新增图标名称
1833
+ const AI_TABLE_CELL_ATTACHMENT_FILE = 'AI_TABLE_CELL_ATTACHMENT_FILE'; // 附件cell中文件
1830
1834
  const AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH = 30; // 字段列头文本的最小宽度
1831
1835
  const AI_TABLE_ROW_SELECT_CHECKBOX = 'AI_TABLE_ROW_SELECT_CHECKBOX'; // 行 checkbox
1832
1836
  const AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX = 'AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX'; // 表头 checkbox 标识
@@ -1863,7 +1867,7 @@ const AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT = 8; // 成员头像与成员名
1863
1867
  const AI_TABLE_FILE_ICON_ITEM_HEIGHT = 20; // 文件字段项高度
1864
1868
  const AI_TABLE_FILE_ICON_SIZE = 20; // 文件图标大小
1865
1869
  const AI_TABLE_CELL_FIELD_ITEM_HEIGHT = 8; // 文件字段项右边距
1866
- const AI_TABLE_FIELD_ITEM_MARGIN_RIGHT = 4; // 文件图标之间的间距
1870
+ const AI_TABLE_FIELD_ITEM_MARGIN_RIGHT = 8; // 文件图标之间的间距
1867
1871
  const AI_TABLE_OPTION_ITEM_PADDING = 10; // 选项按钮间距
1868
1872
  const AI_TABLE_OPTION_ITEM_HEIGHT = 24;
1869
1873
  const AI_TABLE_OPTION_ITEM_FONT_SIZE = 14;
@@ -1886,7 +1890,6 @@ const DBL_CLICK_EDIT_TYPE = [
1886
1890
  AITableFieldType.select,
1887
1891
  AITableFieldType.date,
1888
1892
  AITableFieldType.member,
1889
- AITableFieldType.attachment,
1890
1893
  AITableFieldType.link
1891
1894
  ];
1892
1895
  const MOUSEOVER_EDIT_TYPE = [AITableFieldType.progress, AITableFieldType.rate];
@@ -1974,14 +1977,20 @@ class AITableFieldMenu extends ThyDropdownAbstractMenu {
1974
1977
  menu.exec && menu.exec(this.aiTable, this.field, this.origin, this.position);
1975
1978
  }
1976
1979
  }
1980
+ getMenuName(menu, field) {
1981
+ if (typeof menu.name === 'function') {
1982
+ return menu.name(field);
1983
+ }
1984
+ return menu.name || '';
1985
+ }
1977
1986
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableFieldMenu, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1978
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableFieldMenu, isStandalone: true, selector: "ai-table-field-menu", inputs: { fieldId: "fieldId", aiTable: "aiTable", fieldMenus: "fieldMenus", origin: "origin", position: "position" }, host: { classAttribute: "field-menu" }, usesInheritance: true, ngImport: i0, template: "@for (menu of fieldMenus; track index; let index = $index) {\n @if ((menu.hidden && !menu.hidden(aiTable, field)) || !menu.hidden) {\n @if (menu.type === 'divider') {\n <thy-divider [thyStyle]=\"'solid'\"></thy-divider>\n } @else {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable, field));\n @let isRemoveField = menu.type === 'removeField';\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'remove-field': isRemoveField && !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}\n", dependencies: [{ kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyDivider, selector: "thy-divider", inputs: ["thyVertical", "thyStyle", "thyColor", "thyText", "thyTextDirection", "thyDeeper"] }, { kind: "directive", type: ThyDropdownMenuItemDirective, selector: "[thyDropdownMenuItem]", inputs: ["thyType", "thyDisabled"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1987
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableFieldMenu, isStandalone: true, selector: "ai-table-field-menu", inputs: { fieldId: "fieldId", aiTable: "aiTable", fieldMenus: "fieldMenus", origin: "origin", position: "position" }, host: { classAttribute: "field-menu" }, usesInheritance: true, ngImport: i0, template: "@for (menu of fieldMenus; track index; let index = $index) {\n @if ((menu.hidden && !menu.hidden(aiTable, field)) || !menu.hidden) {\n @if (menu.type === 'divider') {\n <thy-divider [thyStyle]=\"'solid'\"></thy-divider>\n } @else {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable, field));\n @let isRemoveField = menu.type === 'removeField';\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'remove-field': isRemoveField && !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ getMenuName(menu, field()) }}</span>\n </a>\n }\n }\n}\n", dependencies: [{ kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyDivider, selector: "thy-divider", inputs: ["thyVertical", "thyStyle", "thyColor", "thyText", "thyTextDirection", "thyDeeper"] }, { kind: "directive", type: ThyDropdownMenuItemDirective, selector: "[thyDropdownMenuItem]", inputs: ["thyType", "thyDisabled"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1979
1988
  }
1980
1989
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableFieldMenu, decorators: [{
1981
1990
  type: Component,
1982
1991
  args: [{ selector: 'ai-table-field-menu', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
1983
1992
  class: 'field-menu'
1984
- }, imports: [ThyIcon, ThyDivider, ThyDropdownMenuItemDirective, NgClass], template: "@for (menu of fieldMenus; track index; let index = $index) {\n @if ((menu.hidden && !menu.hidden(aiTable, field)) || !menu.hidden) {\n @if (menu.type === 'divider') {\n <thy-divider [thyStyle]=\"'solid'\"></thy-divider>\n } @else {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable, field));\n @let isRemoveField = menu.type === 'removeField';\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'remove-field': isRemoveField && !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}\n" }]
1993
+ }, imports: [ThyIcon, ThyDivider, ThyDropdownMenuItemDirective, NgClass], template: "@for (menu of fieldMenus; track index; let index = $index) {\n @if ((menu.hidden && !menu.hidden(aiTable, field)) || !menu.hidden) {\n @if (menu.type === 'divider') {\n <thy-divider [thyStyle]=\"'solid'\"></thy-divider>\n } @else {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable, field));\n @let isRemoveField = menu.type === 'removeField';\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'remove-field': isRemoveField && !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ getMenuName(menu, field()) }}</span>\n </a>\n }\n }\n}\n" }]
1985
1994
  }], propDecorators: { fieldId: [{
1986
1995
  type: Input,
1987
1996
  args: [{ required: true }]
@@ -2157,9 +2166,9 @@ function getAvatarBgColor(name) {
2157
2166
  /**
2158
2167
  * 生成目标名称
2159
2168
  */
2160
- const generateTargetName = ({ targetName, fieldId, recordId, mouseStyle }) => {
2169
+ const generateTargetName = ({ targetName, fieldId, recordId, mouseStyle, source }) => {
2161
2170
  const flag = '$';
2162
- return `${targetName}.${fieldId || flag}.${recordId || flag}.${mouseStyle || flag}`;
2171
+ return `${targetName}.${fieldId || flag}.${recordId || flag}.${mouseStyle || flag}.${source || flag}`;
2163
2172
  };
2164
2173
  /**
2165
2174
  * 取目标名称
@@ -2182,12 +2191,13 @@ const getDetailByTargetName = (_targetName) => {
2182
2191
  };
2183
2192
  }
2184
2193
  const flag = '$';
2185
- const [targetName, fieldId, recordId, mouseStyle] = _targetName.split('.');
2194
+ const [targetName, fieldId, recordId, mouseStyle, source] = _targetName.split('.');
2186
2195
  return {
2187
2196
  targetName,
2188
2197
  fieldId: fieldId === flag ? null : fieldId,
2189
2198
  recordId: recordId === flag ? null : recordId,
2190
- mouseStyle: mouseStyle === flag ? null : mouseStyle
2199
+ mouseStyle: mouseStyle === flag ? null : mouseStyle,
2200
+ source: source === flag ? null : source
2191
2201
  };
2192
2202
  };
2193
2203
  /**
@@ -2688,21 +2698,15 @@ function toDateFieldValue(plainText, targetField, originData) {
2688
2698
  switch (field.type) {
2689
2699
  case AITableFieldType.date:
2690
2700
  return cellValue;
2691
- case AITableFieldType.text:
2692
- const dateValue = transformDateValue(cellValue);
2693
- if (dateValue) {
2694
- return dateValue;
2695
- }
2696
- break;
2697
2701
  default:
2698
2702
  break;
2699
2703
  }
2700
2704
  }
2701
- else {
2702
- const dateValue = transformDateValue(plainText);
2703
- if (dateValue) {
2704
- return dateValue;
2705
- }
2705
+ const texts = plainText.split(',');
2706
+ const value = texts && texts.length ? texts[0].trim() : plainText.trim();
2707
+ const dateValue = transformDateValue(value);
2708
+ if (dateValue) {
2709
+ return dateValue;
2706
2710
  }
2707
2711
  return null;
2708
2712
  }
@@ -3005,10 +3009,17 @@ function toProgressFieldValue(plainText, targetField, originData) {
3005
3009
  break;
3006
3010
  }
3007
3011
  }
3012
+ const progressRegex = /^(?:100|[1-9]?\d(?:\.\d+)?)\s*%$/;
3013
+ if (progressRegex.test(value)) {
3014
+ value = parseFloat(value);
3015
+ }
3008
3016
  if (!isEmpty(value)) {
3009
- const progressValue = Number(value);
3010
- if (!Number.isNaN(progressValue) && progressValue >= 0 && progressValue <= 100) {
3011
- return progressValue;
3017
+ let progressValue = Number(value);
3018
+ if (!Number.isNaN(progressValue)) {
3019
+ progressValue = Math.round(progressValue);
3020
+ if (progressValue >= 0 && progressValue <= 100) {
3021
+ return progressValue;
3022
+ }
3012
3023
  }
3013
3024
  }
3014
3025
  return null;
@@ -3442,7 +3453,8 @@ function appendRecord(aiTable, actions) {
3442
3453
  });
3443
3454
  }
3444
3455
  function appendField(aiTable, originField, actions) {
3445
- const lastFieldId = aiTable.fields().length > 0 ? aiTable.fields()[aiTable.fields().length - 1]._id : '';
3456
+ const fields = aiTable.gridData().fields;
3457
+ const lastFieldId = fields.length > 0 ? fields[fields.length - 1]._id : '';
3446
3458
  let defaultFieldValue;
3447
3459
  if (originField) {
3448
3460
  defaultFieldValue = {
@@ -5104,927 +5116,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
5104
5116
  }]
5105
5117
  }] });
5106
5118
 
5107
- var cellComponents = /*#__PURE__*/Object.freeze({
5108
- __proto__: null,
5109
- AITableCellLink: AITableCellLink
5110
- });
5111
-
5112
- const componentMap = {};
5113
- Object.values(cellComponents).forEach((cellComponent) => {
5114
- componentMap[cellComponent.fieldType] = cellComponent;
5115
- });
5116
-
5117
- function getHoverCell(aiTable) {
5118
- const pointPosition = aiTable.context.pointPosition();
5119
- const { fieldId, recordId } = getDetailByTargetName(pointPosition.realTargetName) ?? {};
5120
- if (!recordId || !fieldId) {
5121
- return;
5122
- }
5123
- const record = aiTable.recordsMap()[recordId];
5124
- const field = aiTable.fieldsMap()[fieldId];
5125
- if (!record || !field || !recordId || !fieldId) {
5126
- return;
5127
- }
5128
- const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, fieldId]);
5129
- const transformValue = transformCellValue(aiTable, field, cellValue) || {};
5130
- if (Object.keys(transformValue).length === 0) {
5131
- return;
5132
- }
5133
- const renderComponentDefinition = componentMap[field?.type];
5134
- if (!renderComponentDefinition) {
5135
- return;
5136
- }
5137
- return {
5138
- field,
5139
- recordId,
5140
- fieldId,
5141
- renderComponentDefinition
5142
- };
5143
- }
5144
-
5145
- class AITableGridEventService {
5146
- constructor() {
5147
- this.dblClickEvent$ = new Subject();
5148
- this.mousedownEvent$ = new Subject();
5149
- this.mouseoverEvent$ = new Subject();
5150
- this.globalMouseoverEvent$ = new Subject();
5151
- this.globalMousedownEvent$ = new Subject();
5152
- this.destroyRef = inject(DestroyRef);
5153
- this.thyPopover = inject(ThyPopover);
5154
- }
5155
- initialize(aiTable, aiFieldRenderers) {
5156
- this.aiTable = aiTable;
5157
- this.aiFieldRenderers = aiFieldRenderers;
5158
- }
5159
- registerEvents(element) {
5160
- fromEvent(element, 'dblclick', { passive: true })
5161
- .pipe(takeUntilDestroyed(this.destroyRef))
5162
- .subscribe((event) => {
5163
- this.dblClickEvent$.next(event);
5164
- });
5165
- fromEvent(element, 'mouseover', { passive: true })
5166
- .pipe(debounceTime(80), takeUntilDestroyed(this.destroyRef))
5167
- .subscribe((event) => {
5168
- this.mouseoverEvent$.next(event);
5169
- });
5170
- fromEvent(document, 'mouseover', { passive: true })
5171
- .pipe(takeUntilDestroyed(this.destroyRef))
5172
- .subscribe((event) => {
5173
- this.globalMouseoverEvent$.next(event);
5174
- });
5175
- fromEvent(element, 'mousedown', { passive: true })
5176
- .pipe(takeUntilDestroyed(this.destroyRef))
5177
- .subscribe((event) => {
5178
- this.mousedownEvent$.next(event);
5179
- });
5180
- fromEvent(document, 'mousedown', { passive: true })
5181
- .pipe(takeUntilDestroyed(this.destroyRef))
5182
- .subscribe((event) => {
5183
- this.globalMousedownEvent$.next(event);
5184
- });
5185
- }
5186
- getEditorComponent(type) {
5187
- const filedRenderSchema = this.aiFieldRenderers && this.aiFieldRenderers[type];
5188
- if (filedRenderSchema && filedRenderSchema.editor) {
5189
- return {
5190
- component: filedRenderSchema.editor,
5191
- isInternalComponent: false
5192
- };
5193
- }
5194
- return {
5195
- component: GRID_CELL_EDITOR_MAP[type],
5196
- isInternalComponent: true
5197
- };
5198
- }
5199
- openEdit(cellDom) {
5200
- const { x, y, width, height } = cellDom.getBoundingClientRect();
5201
- const fieldId = cellDom.getAttribute('fieldId');
5202
- const recordId = cellDom.getAttribute('recordId');
5203
- const { component } = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
5204
- const ref = this.thyPopover.open(component, {
5205
- origin: cellDom,
5206
- originPosition: {
5207
- x: x - 1,
5208
- y: y + 1,
5209
- width: width + 2,
5210
- height: height + 2
5211
- },
5212
- width: width + 1 + 'px',
5213
- height: height + 2 + 'px',
5214
- placement: 'top',
5215
- offset: -(height + 4),
5216
- minWidth: width,
5217
- initialState: {
5218
- fieldId: fieldId,
5219
- recordId: recordId,
5220
- aiTable: this.aiTable
5221
- },
5222
- panelClass: 'grid-cell-editor',
5223
- outsideClosable: false,
5224
- hasBackdrop: false,
5225
- manualClosure: true,
5226
- animationDisabled: true,
5227
- autoAdaptive: true
5228
- });
5229
- return ref;
5230
- }
5231
- getOriginPosition(aiTable, options) {
5232
- const { container, coordinate, recordId, fieldId, isHoverEdit } = options;
5233
- const { scrollState } = aiTable.context;
5234
- const { rowHeight, columnCount } = coordinate;
5235
- const cell = [recordId, fieldId];
5236
- const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, cell);
5237
- const originX = coordinate.getColumnOffset(columnIndex);
5238
- const originY = coordinate.getRowOffset(rowIndex);
5239
- const columnWidth = coordinate.getColumnWidth(columnIndex);
5240
- const { width: originWidth, offset: originOffset } = getCellHorizontalPosition({
5241
- columnWidth,
5242
- columnIndex,
5243
- columnCount
5244
- });
5245
- const originRect = container.getBoundingClientRect();
5246
- const isFrozenColumn = AITable.isFrozenColumn(aiTable, columnIndex);
5247
- const scrollLeft = isFrozenColumn ? 0 : scrollState().scrollLeft;
5248
- const scrollTop = scrollState().scrollTop;
5249
- const originPosition = {
5250
- x: originX + originOffset - scrollLeft + originRect.x,
5251
- y: originY - scrollTop + originRect.y,
5252
- width: originWidth,
5253
- height: rowHeight
5254
- };
5255
- let x = originPosition.x + getEditorBoxOffset();
5256
- let y = originPosition.y + getEditorBoxOffset();
5257
- let width = getEditorSpace(originPosition.width);
5258
- let height = getEditorSpace(originPosition.height);
5259
- // hover 编辑组件无边框
5260
- if (isHoverEdit) {
5261
- x = originPosition.x + getHoverEditorBoxOffset();
5262
- y = originPosition.y + getHoverEditorBoxOffset();
5263
- width = getHoverEditorSpace(originPosition.width);
5264
- height = getHoverEditorSpace(originPosition.height);
5265
- }
5266
- return {
5267
- ...originPosition,
5268
- x: x,
5269
- y: y,
5270
- width: width,
5271
- height: height
5272
- };
5273
- }
5274
- openCellEditor(aiTable, options) {
5275
- const { container, recordId, fieldId, isHoverEdit, references } = options;
5276
- const { component, isInternalComponent } = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
5277
- const offsetOriginPosition = this.getOriginPosition(aiTable, options);
5278
- this.cellEditorPopoverRef = this.thyPopover.open(component, {
5279
- viewContainerRef: isInternalComponent ? undefined : options?.viewContainerRef,
5280
- origin: container,
5281
- originPosition: offsetOriginPosition,
5282
- width: offsetOriginPosition.width + 'px',
5283
- height: offsetOriginPosition.height + 'px',
5284
- minWidth: offsetOriginPosition.width + 'px',
5285
- placement: 'bottom',
5286
- offset: -offsetOriginPosition.height,
5287
- initialState: {
5288
- fieldId: fieldId,
5289
- recordId: recordId,
5290
- references,
5291
- aiTable: aiTable
5292
- },
5293
- panelClass: 'grid-cell-editor',
5294
- outsideClosable: false,
5295
- hasBackdrop: false,
5296
- manualClosure: true,
5297
- animationDisabled: true,
5298
- autoAdaptive: true
5299
- });
5300
- if (this.cellEditorPopoverRef) {
5301
- const wheelEvent = fromEvent(this.cellEditorPopoverRef.componentInstance.elementRef.nativeElement, 'wheel').subscribe((event) => {
5302
- const field = aiTable.fieldsMap()[fieldId];
5303
- if (field.type === AITableFieldType.text || field.type === AITableFieldType.richText) {
5304
- return;
5305
- }
5306
- event.preventDefault();
5307
- this.aiTable.context?.scrollAction({
5308
- deltaX: event.deltaX,
5309
- deltaY: event.deltaY,
5310
- shiftKey: event.shiftKey,
5311
- callback: () => {
5312
- const originPosition = this.getOriginPosition(aiTable, options);
5313
- const positionStrategy = this.cellEditorPopoverRef
5314
- .getOverlayRef()
5315
- .getConfig().positionStrategy;
5316
- positionStrategy.setOrigin(originPosition);
5317
- positionStrategy.apply();
5318
- }
5319
- });
5320
- });
5321
- this.cellEditorPopoverRef.afterClosed().subscribe(() => {
5322
- wheelEvent.unsubscribe();
5323
- this.cellEditorPopoverRef = null;
5324
- });
5325
- this.cellEditorPopoverRef.componentInstance.updateFieldValue.subscribe((value) => {
5326
- options.updateFieldValue(value);
5327
- });
5328
- }
5329
- return this.cellEditorPopoverRef;
5330
- }
5331
- closeCellEditor() {
5332
- if (this.cellEditorPopoverRef) {
5333
- this.cellEditorPopoverRef.close();
5334
- this.cellEditorPopoverRef = null;
5335
- }
5336
- }
5337
- getCurrentEditCell() {
5338
- if (this.cellEditorPopoverRef) {
5339
- const recordId = this.cellEditorPopoverRef.componentInstance?.recordId;
5340
- const fieldId = this.cellEditorPopoverRef.componentInstance?.fieldId;
5341
- if (recordId && fieldId) {
5342
- return {
5343
- recordId,
5344
- fieldId
5345
- };
5346
- }
5347
- return null;
5348
- }
5349
- return null;
5350
- }
5351
- openContextMenu(aiTable, options) {
5352
- const { origin, position, menuItems, targetName, viewContainerRef } = options;
5353
- const ref = this.thyPopover.open(AITableContextMenu, {
5354
- origin: origin,
5355
- originPosition: position,
5356
- placement: 'bottomLeft',
5357
- insideClosable: true,
5358
- viewContainerRef,
5359
- initialState: {
5360
- aiTable,
5361
- menuItems,
5362
- targetName,
5363
- position
5364
- }
5365
- });
5366
- return ref;
5367
- }
5368
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5369
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService }); }
5370
- }
5371
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, decorators: [{
5372
- type: Injectable
5373
- }] });
5374
-
5375
- class AITableGridBase {
5376
- constructor() {
5377
- this.aiRecords = model.required();
5378
- this.aiFields = model.required();
5379
- this.aiContextMenuItems = input([]);
5380
- this.aiFieldConfig = input();
5381
- this.aiReadonly = input();
5382
- this.aiPlugins = input();
5383
- this.aiReferences = input.required();
5384
- this.aiBuildRenderDataFn = input();
5385
- this.aiKeywords = input();
5386
- this.AITableFieldType = AITableFieldType;
5387
- this.AITableSelectOptionStyle = AITableSelectOptionStyle;
5388
- this.isSelectedAll = computed(() => {
5389
- return this.aiTable.selection().selectedRecords.size === this.aiRecords().length;
5390
- });
5391
- this.aiTableInitialized = output();
5392
- this.aiAddRecord = output();
5393
- this.aiAddField = output();
5394
- this.aiMoveField = output();
5395
- this.aiUpdateFieldValue = output();
5396
- this.aiSetField = output();
5397
- this.fieldMenus = computed(() => {
5398
- return this.aiFieldConfig()?.fieldMenus || [];
5399
- });
5400
- this.gridData = computed(() => {
5401
- if (this.aiBuildRenderDataFn && this.aiBuildRenderDataFn() && this.aiTable) {
5402
- return this.aiBuildRenderDataFn()(this.aiTable);
5403
- }
5404
- return {
5405
- records: this.aiRecords(),
5406
- fields: this.aiFields()
5407
- };
5408
- });
5409
- this.ngZone = inject(NgZone);
5410
- this.elementRef = inject(ElementRef);
5411
- this.destroyRef = inject(DestroyRef);
5412
- this.aiTableGridFieldService = inject(AITableGridFieldService);
5413
- this.aiTableGridEventService = inject(AITableGridEventService);
5414
- this.aiTableGridSelectionService = inject(AITableGridSelectionService);
5415
- }
5416
- ngOnInit() {
5417
- this.initAITable();
5418
- this.initService();
5419
- }
5420
- initAITable() {
5421
- this.aiTable = createAITable(this.aiRecords, this.aiFields, this.gridData);
5422
- this.aiPlugins()?.forEach((plugin) => {
5423
- this.aiTable = plugin(this.aiTable);
5424
- });
5425
- this.aiTableInitialized.emit(this.aiTable);
5426
- }
5427
- initService() {
5428
- this.aiTableGridEventService.initialize(this.aiTable, this.aiFieldConfig()?.fieldRenderers);
5429
- this.aiTableGridSelectionService.initialize(this.aiTable);
5430
- this.aiTableGridEventService.registerEvents(this.elementRef.nativeElement);
5431
- this.aiTableGridFieldService.initAIFieldConfig(this.aiFieldConfig());
5432
- AI_TABLE_GRID_FIELD_SERVICE_MAP.set(this.aiTable, this.aiTableGridFieldService);
5433
- }
5434
- addRecord() {
5435
- const records = this.aiRecords();
5436
- const recordCount = records.length;
5437
- this.aiAddRecord.emit({
5438
- originId: recordCount > 0 ? records[records.length - 1]._id : ''
5439
- });
5440
- }
5441
- selectRecord(recordId) {
5442
- this.aiTableGridSelectionService.selectRecord(recordId);
5443
- }
5444
- toggleSelectAll(checked) {
5445
- this.aiTableGridSelectionService.toggleSelectAll(checked);
5446
- }
5447
- addField(gridColumnBlank, position) {
5448
- const field = createDefaultField(this.aiTable, AITableFieldType.text);
5449
- const popoverRef = this.aiTableGridFieldService.editFieldProperty(this.aiTable, {
5450
- field,
5451
- isUpdate: false,
5452
- origin: gridColumnBlank,
5453
- position
5454
- });
5455
- if (popoverRef && !this.aiFieldConfig()?.fieldSettingComponent) {
5456
- popoverRef.componentInstance.addField.subscribe((defaultValue) => {
5457
- const fields = this.gridData().fields;
5458
- const fieldCount = fields.length;
5459
- this.aiAddField.emit({
5460
- originId: fieldCount > 0 ? fields[fields.length - 1]._id : '',
5461
- defaultValue
5462
- });
5463
- });
5464
- }
5465
- }
5466
- subscribeEvents() {
5467
- this.ngZone.runOutsideAngular(() => {
5468
- this.aiTableGridEventService.dblClickEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
5469
- this.dblClick(event);
5470
- });
5471
- this.aiTableGridEventService.mousedownEvent$
5472
- .pipe(mergeWith(this.aiTableGridEventService.globalMousedownEvent$), takeUntilDestroyed(this.destroyRef))
5473
- .subscribe((event) => {
5474
- this.aiTableGridSelectionService.updateSelect(event);
5475
- });
5476
- this.aiTableGridEventService.mouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
5477
- this.mouseoverHandle(event);
5478
- });
5479
- this.aiTableGridEventService.globalMouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
5480
- this.closeHoverCellEditor(event);
5481
- });
5482
- });
5483
- }
5484
- dblClick(event) {
5485
- const cellDom = event.target.closest('.grid-cell');
5486
- const type = cellDom && cellDom.getAttribute('type');
5487
- if (type && DBL_CLICK_EDIT_TYPE.includes(type)) {
5488
- this.aiTableGridEventService.openEdit(cellDom);
5489
- }
5490
- }
5491
- mouseoverHandle(event) {
5492
- if (this.mouseoverRef) {
5493
- this.mouseoverRef?.close();
5494
- }
5495
- const cellDom = event.target.closest('.grid-cell');
5496
- const type = cellDom && cellDom.getAttribute('type');
5497
- if (type && MOUSEOVER_EDIT_TYPE.includes(type)) {
5498
- this.mouseoverRef = this.aiTableGridEventService.openEdit(cellDom);
5499
- }
5500
- }
5501
- closeHoverCellEditor(e) {
5502
- if (this.mouseoverRef) {
5503
- const hasGrid = e.target && e.target.closest('.ai-table-grid');
5504
- const hasCellEditor = e.target && e.target.closest('.grid-cell-editor');
5505
- if (!hasGrid && !hasCellEditor) {
5506
- this.mouseoverRef.close();
5507
- }
5508
- }
5509
- }
5510
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5511
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableGridBase, isStandalone: true, selector: "ai-table-grid-base", inputs: { aiRecords: { classPropertyName: "aiRecords", publicName: "aiRecords", isSignal: true, isRequired: true, transformFunction: null }, aiFields: { classPropertyName: "aiFields", publicName: "aiFields", isSignal: true, isRequired: true, transformFunction: null }, aiContextMenuItems: { classPropertyName: "aiContextMenuItems", publicName: "aiContextMenuItems", isSignal: true, isRequired: false, transformFunction: null }, aiFieldConfig: { classPropertyName: "aiFieldConfig", publicName: "aiFieldConfig", isSignal: true, isRequired: false, transformFunction: null }, aiReadonly: { classPropertyName: "aiReadonly", publicName: "aiReadonly", isSignal: true, isRequired: false, transformFunction: null }, aiPlugins: { classPropertyName: "aiPlugins", publicName: "aiPlugins", isSignal: true, isRequired: false, transformFunction: null }, aiReferences: { classPropertyName: "aiReferences", publicName: "aiReferences", isSignal: true, isRequired: true, transformFunction: null }, aiBuildRenderDataFn: { classPropertyName: "aiBuildRenderDataFn", publicName: "aiBuildRenderDataFn", isSignal: true, isRequired: false, transformFunction: null }, aiKeywords: { classPropertyName: "aiKeywords", publicName: "aiKeywords", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiRecords: "aiRecordsChange", aiFields: "aiFieldsChange", aiTableInitialized: "aiTableInitialized", aiAddRecord: "aiAddRecord", aiAddField: "aiAddField", aiMoveField: "aiMoveField", aiUpdateFieldValue: "aiUpdateFieldValue", aiSetField: "aiSetField" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5512
- }
5513
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, decorators: [{
5514
- type: Component,
5515
- args: [{
5516
- selector: 'ai-table-grid-base',
5517
- template: '',
5518
- standalone: true,
5519
- changeDetection: ChangeDetectionStrategy.OnPush
5520
- }]
5521
- }] });
5522
-
5523
- class AITableDomGrid extends AITableGridBase {
5524
- ngOnInit() {
5525
- super.ngOnInit();
5526
- this.subscribeEvents();
5527
- }
5528
- openFieldMenu(e, field, fieldAction) {
5529
- const moreBtn = e.target.closest('.grid-field-action');
5530
- this.aiTableGridFieldService.openFieldMenu(this.aiTable, {
5531
- origin: moreBtn,
5532
- editOrigin: fieldAction,
5533
- fieldId: field._id,
5534
- fieldMenus: this.fieldMenus()
5535
- });
5536
- }
5537
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
5538
- 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 }); }
5539
- }
5540
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, decorators: [{
5541
- type: Component,
5542
- args: [{ selector: 'ai-table-dom-grid', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
5543
- class: 'ai-table-grid ai-table-dom-grid'
5544
- }, imports: [
5545
- NgClass,
5546
- NgComponentOutlet,
5547
- CommonModule,
5548
- FormsModule,
5549
- SelectOptionPipe,
5550
- SelectOptionsPipe,
5551
- ThyTag,
5552
- ThyPopoverModule,
5553
- ThyIcon,
5554
- ThyRate,
5555
- ThyProgress,
5556
- AITableFieldSetting,
5557
- ThyDatePickerFormatPipe,
5558
- ThyFlexibleText,
5559
- ThyStopPropagationDirective,
5560
- AITableFieldMenu,
5561
- ThyAction,
5562
- ThyDropdownDirective,
5563
- ThyDropdownMenuComponent,
5564
- ThyCheckboxModule,
5565
- ProgressEditorComponent,
5566
- ThyAvatarModule,
5567
- NgTemplateOutlet,
5568
- IsSelectRecordPipe,
5569
- ProgressEditorComponent,
5570
- SelectOptionComponent,
5571
- UserPipe,
5572
- SelectSettingPipe,
5573
- MemberSettingPipe
5574
- ], 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" }]
5575
- }] });
5576
-
5577
- class KoStage {
5578
- constructor() {
5579
- this.config = input();
5580
- this.koMouseover = new EventEmitter();
5581
- this.koMousemove = new EventEmitter();
5582
- this.koMouseout = new EventEmitter();
5583
- this.koMouseenter = new EventEmitter();
5584
- this.koMouseleave = new EventEmitter();
5585
- this.koMousedown = new EventEmitter();
5586
- this.koMouseup = new EventEmitter();
5587
- this.koWheel = new EventEmitter();
5588
- this.koContextmenu = new EventEmitter();
5589
- this.koClick = new EventEmitter();
5590
- this.koDblclick = new EventEmitter();
5591
- this.koTouchstart = new EventEmitter();
5592
- this.koTouchmove = new EventEmitter();
5593
- this.koTouchend = new EventEmitter();
5594
- this.koTap = new EventEmitter();
5595
- this.koDbltap = new EventEmitter();
5596
- this.koDragstart = new EventEmitter();
5597
- this.koDragmove = new EventEmitter();
5598
- this.koDragend = new EventEmitter();
5599
- this.cacheProps = {};
5600
- this.nodeContainer = inject(ElementRef).nativeElement;
5601
- effect(() => {
5602
- if (this.config()) {
5603
- if (!this._stage) {
5604
- this.initStage();
5605
- }
5606
- this.updateNode(this.config());
5607
- }
5608
- });
5609
- }
5610
- ngOnInit() {
5611
- this.initStage();
5612
- }
5613
- getNode() {
5614
- return this._stage;
5615
- }
5616
- initStage() {
5617
- this._stage = new Stage({
5618
- ...this.config(),
5619
- container: this.nodeContainer
5620
- });
5621
- }
5622
- updateNode(config) {
5623
- const props = {
5624
- ...config,
5625
- ...createListener(this)
5626
- };
5627
- applyNodeProps(this, props, this.cacheProps);
5628
- this.cacheProps = props;
5629
- }
5630
- ngOnDestroy() {
5631
- this._stage?.destroy();
5632
- }
5633
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5634
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: KoStage, isStandalone: true, selector: "ko-stage", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { koMouseover: "koMouseover", koMousemove: "koMousemove", koMouseout: "koMouseout", koMouseenter: "koMouseenter", koMouseleave: "koMouseleave", koMousedown: "koMousedown", koMouseup: "koMouseup", koWheel: "koWheel", koContextmenu: "koContextmenu", koClick: "koClick", koDblclick: "koDblclick", koTouchstart: "koTouchstart", koTouchmove: "koTouchmove", koTouchend: "koTouchend", koTap: "koTap", koDbltap: "koDbltap", koDragstart: "koDragstart", koDragmove: "koDragmove", koDragend: "koDragend" }, providers: [
5635
- {
5636
- provide: KO_CONTAINER_TOKEN,
5637
- useExisting: KoStage
5638
- }
5639
- ], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5640
- }
5641
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, decorators: [{
5642
- type: Component,
5643
- args: [{
5644
- selector: 'ko-stage',
5645
- standalone: true,
5646
- template: `<ng-content></ng-content>`,
5647
- providers: [
5648
- {
5649
- provide: KO_CONTAINER_TOKEN,
5650
- useExisting: KoStage
5651
- }
5652
- ],
5653
- changeDetection: ChangeDetectionStrategy.OnPush
5654
- }]
5655
- }], ctorParameters: () => [], propDecorators: { koMouseover: [{
5656
- type: Output
5657
- }], koMousemove: [{
5658
- type: Output
5659
- }], koMouseout: [{
5660
- type: Output
5661
- }], koMouseenter: [{
5662
- type: Output
5663
- }], koMouseleave: [{
5664
- type: Output
5665
- }], koMousedown: [{
5666
- type: Output
5667
- }], koMouseup: [{
5668
- type: Output
5669
- }], koWheel: [{
5670
- type: Output
5671
- }], koContextmenu: [{
5672
- type: Output
5673
- }], koClick: [{
5674
- type: Output
5675
- }], koDblclick: [{
5676
- type: Output
5677
- }], koTouchstart: [{
5678
- type: Output
5679
- }], koTouchmove: [{
5680
- type: Output
5681
- }], koTouchend: [{
5682
- type: Output
5683
- }], koTap: [{
5684
- type: Output
5685
- }], koDbltap: [{
5686
- type: Output
5687
- }], koDragstart: [{
5688
- type: Output
5689
- }], koDragmove: [{
5690
- type: Output
5691
- }], koDragend: [{
5692
- type: Output
5693
- }] } });
5694
-
5695
- class KoComponent extends Component {
5696
- }
5697
-
5698
- const KoShapeTypes = {
5699
- Arc,
5700
- Arrow,
5701
- Circle,
5702
- Ellipse,
5703
- Image: Image$1,
5704
- Label,
5705
- Tag,
5706
- Line,
5707
- Path,
5708
- Rect,
5709
- RegularPolygon,
5710
- Ring,
5711
- Star,
5712
- Text,
5713
- TextPath,
5714
- Transformer,
5715
- Wedge,
5716
- Group,
5717
- Layer,
5718
- FastLayer
5719
- };
5720
-
5721
- class AITableIcon {
5722
- constructor() {
5723
- this.config = input.required();
5724
- this.groupConfig = computed(() => {
5725
- const { x, y, listening } = this.config();
5726
- return { x, y, listening };
5727
- });
5728
- this.squareShapeConfig = computed(() => {
5729
- const { name, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, strokeWidth = 1, background, cornerRadius, opacity } = this.config();
5730
- return {
5731
- name,
5732
- width: backgroundWidth || size,
5733
- height: backgroundHeight || size,
5734
- strokeWidth: strokeWidth,
5735
- fill: background || Colors.transparent,
5736
- cornerRadius,
5737
- opacity
5738
- };
5739
- });
5740
- this.iconConfig = computed(() => {
5741
- const { type, data, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, stroke, strokeWidth = 1, scaleX, scaleY, offsetX, offsetY, rotation, fill = Colors.gray600, transformsEnabled = 'position' } = this.config();
5742
- let pathData = data;
5743
- switch (type) {
5744
- case AITableCheckType.checked:
5745
- pathData = Check;
5746
- break;
5747
- case AITableCheckType.unchecked:
5748
- pathData = Unchecked;
5749
- break;
5750
- }
5751
- return {
5752
- x: backgroundWidth && (backgroundWidth - size * (scaleX || 1)) / 2,
5753
- y: backgroundHeight && (backgroundHeight - size * (scaleY || 1)) / 2,
5754
- data: pathData,
5755
- width: size,
5756
- height: size,
5757
- fill,
5758
- offsetX,
5759
- offsetY,
5760
- scaleX,
5761
- scaleY,
5762
- rotation,
5763
- stroke,
5764
- strokeWidth,
5765
- transformsEnabled,
5766
- perfectDrawEnabled: false,
5767
- listening: false
5768
- };
5769
- });
5770
- }
5771
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5772
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableIcon, isStandalone: true, selector: "ai-table-icon", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
5773
- <ko-group [config]="groupConfig()">
5774
- <ko-rect [config]="squareShapeConfig()"></ko-rect>
5775
- <ko-path [config]="iconConfig()"></ko-path>
5776
- </ko-group>
5777
- `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5778
- }
5779
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, decorators: [{
5780
- type: Component,
5781
- args: [{
5782
- selector: 'ai-table-icon',
5783
- template: `
5784
- <ko-group [config]="groupConfig()">
5785
- <ko-rect [config]="squareShapeConfig()"></ko-rect>
5786
- <ko-path [config]="iconConfig()"></ko-path>
5787
- </ko-group>
5788
- `,
5789
- standalone: true,
5790
- imports: [KoContainer, KoShape],
5791
- changeDetection: ChangeDetectionStrategy.OnPush
5792
- }]
5793
- }] });
5794
-
5795
- class AITableAddField {
5796
- constructor() {
5797
- this.config = input.required();
5798
- this.btnWidth = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
5799
- this.x = computed(() => {
5800
- const lastColumnWidth = this.config().coordinate.getColumnWidth(this.config().columnStopIndex);
5801
- const lastColumnOffset = this.config().coordinate.getColumnOffset(this.config().columnStopIndex);
5802
- return lastColumnWidth + lastColumnOffset;
5803
- });
5804
- this.rectConfig = computed(() => {
5805
- const { pointPosition: { targetName }, readonly } = this.config();
5806
- const fill = targetName === AI_TABLE_FIELD_ADD_BUTTON ? Colors.gray80 : Colors.white;
5807
- return {
5808
- name: generateTargetName({
5809
- targetName: AI_TABLE_FIELD_ADD_BUTTON,
5810
- fieldId: this.config().fields[this.config().columnStopIndex]._id,
5811
- mouseStyle: readonly ? 'default' : 'pointer'
5812
- }),
5813
- x: AI_TABLE_OFFSET,
5814
- y: AI_TABLE_OFFSET,
5815
- width: this.config().coordinate.containerWidth - this.x() < this.btnWidth
5816
- ? this.btnWidth
5817
- : this.config().coordinate.containerWidth - this.x(),
5818
- height: this.config().coordinate.rowInitSize,
5819
- stroke: Colors.gray200,
5820
- strokeWidth: 1,
5821
- listening: true,
5822
- fill
5823
- };
5824
- });
5825
- this.addIconConfig = computed(() => {
5826
- const { readonly } = this.config();
5827
- const offsetY = (this.config().coordinate.rowInitSize - AI_TABLE_ICON_COMMON_SIZE) / 2;
5828
- return {
5829
- x: AI_TABLE_CELL_PADDING,
5830
- y: offsetY,
5831
- data: AddOutlinedPath,
5832
- fill: Colors.gray600,
5833
- listening: false,
5834
- visible: isNil(readonly) ? true : !readonly
5835
- };
5836
- });
5837
- }
5838
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5839
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableAddField, isStandalone: true, selector: "ai-table-add-field", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
5840
- <ko-group [config]="{ x: x() }">
5841
- <ko-group>
5842
- <ko-rect [config]="rectConfig()"></ko-rect>
5843
- </ko-group>
5844
- <ko-group>
5845
- @if (addIconConfig().visible) {
5846
- <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
5847
- }
5848
- </ko-group>
5849
- </ko-group>
5850
- `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { 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: AITableIcon, selector: "ai-table-icon", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5851
- }
5852
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, decorators: [{
5853
- type: Component,
5854
- args: [{
5855
- selector: 'ai-table-add-field',
5856
- template: `
5857
- <ko-group [config]="{ x: x() }">
5858
- <ko-group>
5859
- <ko-rect [config]="rectConfig()"></ko-rect>
5860
- </ko-group>
5861
- <ko-group>
5862
- @if (addIconConfig().visible) {
5863
- <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
5864
- }
5865
- </ko-group>
5866
- </ko-group>
5867
- `,
5868
- standalone: true,
5869
- imports: [KoContainer, KoShape, AITableIcon],
5870
- changeDetection: ChangeDetectionStrategy.OnPush
5871
- }]
5872
- }] });
5873
-
5874
- /**
5875
- * 用于处理表格行或单元格的布局和绘制。
5876
- * 它提供了基本的布局信息(如位置、大小等),并定义了常用的绘图方法(如渲染缩进区域、添加新字段的空白区域等)。
5877
- * 该类继承自 Drawer,并被其他更具体的布局类(如 RecordRowLayout)扩展和使用
5878
- */
5879
- class Layout extends Drawer {
5880
- constructor() {
5881
- super(...arguments);
5882
- // 定义当前单元格或行的位置
5883
- this.x = 0;
5884
- this.y = 0;
5885
- // 行高
5886
- this.rowHeight = 0;
5887
- // 列宽
5888
- this.columnWidth = 0;
5889
- // 行索引
5890
- this.rowIndex = 0;
5891
- // 列索引
5892
- this.columnIndex = 0;
5893
- // 列数
5894
- this.columnCount = 0;
5895
- this.containerWidth = 0;
5896
- }
5897
- // 用于初始化或重置布局的基本属性。这个方法通常在每次渲染新的一行或单元格时调用,确保布局信息是最新的
5898
- init({ x, y, rowIndex, columnIndex, rowHeight, columnWidth, columnCount, containerWidth }) {
5899
- this.x = x;
5900
- this.y = y;
5901
- this.rowIndex = rowIndex;
5902
- this.columnIndex = columnIndex;
5903
- this.rowHeight = rowHeight;
5904
- this.columnWidth = columnWidth;
5905
- this.columnCount = columnCount;
5906
- this.containerWidth = containerWidth;
5907
- }
5908
- // 当前单元格是否是行的第一列
5909
- get isFirst() {
5910
- return this.columnIndex === 0;
5911
- }
5912
- // 当前单元格是否是行的最后一列
5913
- get isLast() {
5914
- return this.columnIndex === this.columnCount - 1;
5915
- }
5916
- renderAddFieldBlank({ isHoverRow, isCheckedRow }) {
5917
- const rowHeight = this.rowHeight;
5918
- const fill = isCheckedRow ? this.colors.itemActiveBgColor : isHoverRow ? this.colors.gray80 : this.colors.transparent;
5919
- const addFieldBlankX = this.x + this.columnWidth + AI_TABLE_OFFSET;
5920
- this.rect({
5921
- x: addFieldBlankX,
5922
- y: this.y + AI_TABLE_OFFSET,
5923
- width: this.containerWidth - addFieldBlankX < AI_TABLE_FIELD_ADD_BUTTON_WIDTH
5924
- ? AI_TABLE_FIELD_ADD_BUTTON_WIDTH
5925
- : this.containerWidth - addFieldBlankX,
5926
- height: rowHeight,
5927
- fill
5928
- });
5929
- }
5930
- }
5931
-
5932
- class AddRowLayout extends Layout {
5933
- renderAddFieldBlank({ isHoverRow, isCheckedRow }) {
5934
- super.renderAddFieldBlank({ isHoverRow, isCheckedRow });
5935
- const rowHeight = this.rowHeight;
5936
- const defaultWidth = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
5937
- const width = this.containerWidth - this.x < defaultWidth ? defaultWidth : this.containerWidth - this.x;
5938
- this.line({
5939
- x: this.x + this.columnWidth,
5940
- y: this.y,
5941
- points: [0, rowHeight, width, rowHeight],
5942
- stroke: this.colors.gray200
5943
- });
5944
- }
5945
- renderCell({ width, isHoverRow }) {
5946
- const x = this.x;
5947
- const y = this.y;
5948
- const rowHeight = this.rowHeight;
5949
- const fill = isHoverRow ? this.colors.gray80 : this.colors.transparent;
5950
- this.rect({
5951
- x,
5952
- y: y + AI_TABLE_OFFSET,
5953
- width: width,
5954
- height: rowHeight,
5955
- fill
5956
- });
5957
- this.line({
5958
- x,
5959
- y: y + rowHeight,
5960
- points: [0, 0, width, 0],
5961
- stroke: this.colors.gray200
5962
- });
5963
- }
5964
- renderFirstCell({ isHoverRow }) {
5965
- if (!this.isFirst)
5966
- return;
5967
- const y = this.y;
5968
- const rowHeight = this.rowHeight;
5969
- const columnWidth = this.columnWidth;
5970
- const frozenOffset = AI_TABLE_OFFSET;
5971
- const fill = isHoverRow ? this.colors.gray80 : this.colors.transparent;
5972
- this.rect({
5973
- x: frozenOffset,
5974
- y: y + AI_TABLE_OFFSET,
5975
- width: columnWidth + AI_TABLE_ROW_HEAD_WIDTH - frozenOffset + 1,
5976
- height: rowHeight,
5977
- fill
5978
- });
5979
- this.line({
5980
- x: frozenOffset,
5981
- y,
5982
- points: [0, rowHeight, columnWidth + AI_TABLE_ROW_HEAD_WIDTH - frozenOffset + 1, rowHeight],
5983
- stroke: this.colors.gray200
5984
- });
5985
- this.path({
5986
- x: AI_TABLE_CELL_PADDING,
5987
- y: y + (rowHeight - AI_TABLE_ICON_COMMON_SIZE) / 2 - AI_TABLE_OFFSET,
5988
- data: AddOutlinedPath,
5989
- size: AI_TABLE_ROW_HEAD_SIZE,
5990
- fill: this.colors.gray600
5991
- });
5992
- }
5993
- renderLastCell({ isHoverRow, isCheckedRow }) {
5994
- if (!this.isLast)
5995
- return;
5996
- const width = this.columnWidth;
5997
- if (!this.isFirst) {
5998
- this.renderCell({
5999
- width,
6000
- isHoverRow
6001
- });
6002
- }
6003
- this.renderAddFieldBlank({ isHoverRow, isCheckedRow });
6004
- }
6005
- renderCommonCell({ isHoverRow }) {
6006
- if (this.isFirst || this.isLast)
6007
- return;
6008
- this.renderCell({
6009
- width: this.columnWidth,
6010
- isHoverRow
6011
- });
6012
- }
6013
- render({ isHoverRow, isCheckedRow }) {
6014
- this.renderFirstCell({
6015
- isHoverRow
6016
- });
6017
- this.renderCommonCell({
6018
- isHoverRow
6019
- });
6020
- this.renderLastCell({
6021
- isHoverRow,
6022
- isCheckedRow
6023
- });
6024
- }
6025
- }
6026
- const addRowLayout = new AddRowLayout();
6027
-
6028
5119
  // 自动生成的图标常量文件
6029
5120
  const apk = `<?xml version="1.0" encoding="UTF-8"?>
6030
5121
  <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
@@ -6367,293 +5458,1259 @@ const zip = `<?xml version="1.0" encoding="UTF-8"?>
6367
5458
  </g>
6368
5459
  </svg>`;
6369
5460
 
6370
- var fileIcons = /*#__PURE__*/Object.freeze({
5461
+ function getFileThumbnailSvgString(ext) {
5462
+ let result = 'defaultFile';
5463
+ switch (ext) {
5464
+ case 'doc':
5465
+ case 'docx':
5466
+ result = doc;
5467
+ break;
5468
+ case 'ppt':
5469
+ case 'pptx':
5470
+ result = ppt;
5471
+ break;
5472
+ case 'xls':
5473
+ case 'xlsx':
5474
+ result = xls;
5475
+ break;
5476
+ case 'css':
5477
+ case 'scss':
5478
+ case 'sass':
5479
+ case 'less':
5480
+ result = css;
5481
+ break;
5482
+ case 'png':
5483
+ case 'jpeg':
5484
+ case 'jpg':
5485
+ case 'gif':
5486
+ case 'bmp':
5487
+ case 'svg':
5488
+ result = img;
5489
+ break;
5490
+ case 'mp4':
5491
+ case 'mkv':
5492
+ case 'webm':
5493
+ case 'mov':
5494
+ case 'flv':
5495
+ case '3gp':
5496
+ case 'mpv':
5497
+ case 'avi':
5498
+ case 'mpeg':
5499
+ case 'wmv':
5500
+ result = video;
5501
+ break;
5502
+ case 'mp3':
5503
+ case 'wma':
5504
+ case 'wav':
5505
+ case 'ape':
5506
+ case 'flac':
5507
+ case 'ogg':
5508
+ case 'm4r':
5509
+ case 'm4a':
5510
+ result = mp3;
5511
+ break;
5512
+ case 'pdf':
5513
+ result = pdf;
5514
+ break;
5515
+ case 'txt':
5516
+ result = txt;
5517
+ break;
5518
+ case 'apk':
5519
+ result = apk;
5520
+ break;
5521
+ case 'bak':
5522
+ result = apk;
5523
+ break;
5524
+ case 'cs':
5525
+ result = cs;
5526
+ break;
5527
+ case 'csv':
5528
+ result = csv;
5529
+ break;
5530
+ case 'exe':
5531
+ result = exe;
5532
+ break;
5533
+ case 'fla':
5534
+ result = fla;
5535
+ break;
5536
+ case 'html':
5537
+ result = html;
5538
+ break;
5539
+ case 'ipa':
5540
+ result = ipa;
5541
+ break;
5542
+ case 'java':
5543
+ result = java;
5544
+ break;
5545
+ case 'js':
5546
+ result = js;
5547
+ break;
5548
+ case 'php':
5549
+ result = php;
5550
+ break;
5551
+ case 'rar':
5552
+ result = rar;
5553
+ break;
5554
+ case 'swf':
5555
+ result = swf;
5556
+ break;
5557
+ case 'ttf':
5558
+ result = ttf;
5559
+ break;
5560
+ case 'vss':
5561
+ result = vss;
5562
+ break;
5563
+ case 'xsd':
5564
+ result = xsd;
5565
+ break;
5566
+ case 'zip':
5567
+ result = zip;
5568
+ break;
5569
+ default:
5570
+ result = defaultFile;
5571
+ break;
5572
+ }
5573
+ return result;
5574
+ }
5575
+
5576
+ class KoStage {
5577
+ constructor() {
5578
+ this.config = input();
5579
+ this.koMouseover = new EventEmitter();
5580
+ this.koMousemove = new EventEmitter();
5581
+ this.koMouseout = new EventEmitter();
5582
+ this.koMouseenter = new EventEmitter();
5583
+ this.koMouseleave = new EventEmitter();
5584
+ this.koMousedown = new EventEmitter();
5585
+ this.koMouseup = new EventEmitter();
5586
+ this.koWheel = new EventEmitter();
5587
+ this.koContextmenu = new EventEmitter();
5588
+ this.koClick = new EventEmitter();
5589
+ this.koDblclick = new EventEmitter();
5590
+ this.koTouchstart = new EventEmitter();
5591
+ this.koTouchmove = new EventEmitter();
5592
+ this.koTouchend = new EventEmitter();
5593
+ this.koTap = new EventEmitter();
5594
+ this.koDbltap = new EventEmitter();
5595
+ this.koDragstart = new EventEmitter();
5596
+ this.koDragmove = new EventEmitter();
5597
+ this.koDragend = new EventEmitter();
5598
+ this.cacheProps = {};
5599
+ this.nodeContainer = inject(ElementRef).nativeElement;
5600
+ effect(() => {
5601
+ if (this.config()) {
5602
+ if (!this._stage) {
5603
+ this.initStage();
5604
+ }
5605
+ this.updateNode(this.config());
5606
+ }
5607
+ });
5608
+ }
5609
+ ngOnInit() {
5610
+ this.initStage();
5611
+ }
5612
+ getNode() {
5613
+ return this._stage;
5614
+ }
5615
+ initStage() {
5616
+ this._stage = new Stage({
5617
+ ...this.config(),
5618
+ container: this.nodeContainer
5619
+ });
5620
+ }
5621
+ updateNode(config) {
5622
+ const props = {
5623
+ ...config,
5624
+ ...createListener(this)
5625
+ };
5626
+ applyNodeProps(this, props, this.cacheProps);
5627
+ this.cacheProps = props;
5628
+ }
5629
+ ngOnDestroy() {
5630
+ this._stage?.destroy();
5631
+ }
5632
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5633
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: KoStage, isStandalone: true, selector: "ko-stage", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { koMouseover: "koMouseover", koMousemove: "koMousemove", koMouseout: "koMouseout", koMouseenter: "koMouseenter", koMouseleave: "koMouseleave", koMousedown: "koMousedown", koMouseup: "koMouseup", koWheel: "koWheel", koContextmenu: "koContextmenu", koClick: "koClick", koDblclick: "koDblclick", koTouchstart: "koTouchstart", koTouchmove: "koTouchmove", koTouchend: "koTouchend", koTap: "koTap", koDbltap: "koDbltap", koDragstart: "koDragstart", koDragmove: "koDragmove", koDragend: "koDragend" }, providers: [
5634
+ {
5635
+ provide: KO_CONTAINER_TOKEN,
5636
+ useExisting: KoStage
5637
+ }
5638
+ ], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5639
+ }
5640
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, decorators: [{
5641
+ type: Component,
5642
+ args: [{
5643
+ selector: 'ko-stage',
5644
+ standalone: true,
5645
+ template: `<ng-content></ng-content>`,
5646
+ providers: [
5647
+ {
5648
+ provide: KO_CONTAINER_TOKEN,
5649
+ useExisting: KoStage
5650
+ }
5651
+ ],
5652
+ changeDetection: ChangeDetectionStrategy.OnPush
5653
+ }]
5654
+ }], ctorParameters: () => [], propDecorators: { koMouseover: [{
5655
+ type: Output
5656
+ }], koMousemove: [{
5657
+ type: Output
5658
+ }], koMouseout: [{
5659
+ type: Output
5660
+ }], koMouseenter: [{
5661
+ type: Output
5662
+ }], koMouseleave: [{
5663
+ type: Output
5664
+ }], koMousedown: [{
5665
+ type: Output
5666
+ }], koMouseup: [{
5667
+ type: Output
5668
+ }], koWheel: [{
5669
+ type: Output
5670
+ }], koContextmenu: [{
5671
+ type: Output
5672
+ }], koClick: [{
5673
+ type: Output
5674
+ }], koDblclick: [{
5675
+ type: Output
5676
+ }], koTouchstart: [{
5677
+ type: Output
5678
+ }], koTouchmove: [{
5679
+ type: Output
5680
+ }], koTouchend: [{
5681
+ type: Output
5682
+ }], koTap: [{
5683
+ type: Output
5684
+ }], koDbltap: [{
5685
+ type: Output
5686
+ }], koDragstart: [{
5687
+ type: Output
5688
+ }], koDragmove: [{
5689
+ type: Output
5690
+ }], koDragend: [{
5691
+ type: Output
5692
+ }] } });
5693
+
5694
+ class KoComponent extends Component {
5695
+ }
5696
+
5697
+ const KoShapeTypes = {
5698
+ Arc,
5699
+ Arrow,
5700
+ Circle,
5701
+ Ellipse,
5702
+ Image: Image$1,
5703
+ Label,
5704
+ Tag,
5705
+ Line,
5706
+ Path,
5707
+ Rect,
5708
+ RegularPolygon,
5709
+ Ring,
5710
+ Star,
5711
+ Text,
5712
+ TextPath,
5713
+ Transformer,
5714
+ Wedge,
5715
+ Group,
5716
+ Layer,
5717
+ FastLayer
5718
+ };
5719
+
5720
+ class AITableActionIcon {
5721
+ constructor() {
5722
+ this.onClick = output();
5723
+ this.onMousemove = output();
5724
+ this.onMouseenter = output();
5725
+ this.onMouseleave = output();
5726
+ this.config = input.required();
5727
+ this.isHover = signal(false);
5728
+ this.groupConfig = computed(() => {
5729
+ const { x, y, listening } = this.config();
5730
+ return { x, y, listening };
5731
+ });
5732
+ this.squareShapeConfig = computed(() => {
5733
+ const { name, backgroundWidth, backgroundHeight, hoverFill, size = DEFAULT_ICON_SIZE, strokeWidth = 1, cornerRadius } = this.config();
5734
+ return {
5735
+ name,
5736
+ width: backgroundWidth || size,
5737
+ height: backgroundHeight || size,
5738
+ strokeWidth: strokeWidth,
5739
+ fill: hoverFill && this.isHover() ? hoverFill : Colors.transparent,
5740
+ opacity: hoverFill && this.isHover() ? 0.1 : 1,
5741
+ cornerRadius
5742
+ };
5743
+ });
5744
+ this.iconConfig = computed(() => {
5745
+ let { type, data, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, stroke, strokeWidth = 1, scaleX, scaleY, offsetX, offsetY, rotation, fill, hoverFill, transformsEnabled = 'position' } = this.config();
5746
+ fill = fill || Colors.gray600;
5747
+ let pathData = data;
5748
+ switch (type) {
5749
+ case AITableCheckType.checked:
5750
+ pathData = Check;
5751
+ break;
5752
+ case AITableCheckType.unchecked:
5753
+ pathData = Unchecked;
5754
+ break;
5755
+ }
5756
+ return {
5757
+ x: backgroundWidth && (backgroundWidth - size * (scaleX || 1)) / 2,
5758
+ y: backgroundHeight && (backgroundHeight - size * (scaleY || 1)) / 2,
5759
+ data: pathData,
5760
+ width: size,
5761
+ height: size,
5762
+ fill: hoverFill && this.isHover() ? hoverFill : fill,
5763
+ offsetX,
5764
+ offsetY,
5765
+ scaleX,
5766
+ scaleY,
5767
+ rotation,
5768
+ stroke,
5769
+ strokeWidth,
5770
+ transformsEnabled,
5771
+ perfectDrawEnabled: false,
5772
+ listening: false
5773
+ };
5774
+ });
5775
+ }
5776
+ koClick(e) {
5777
+ this.onClick.emit(e);
5778
+ }
5779
+ koMousemove(e) {
5780
+ e.event.cancelBubble = true;
5781
+ }
5782
+ koMouseenter(e) {
5783
+ this.onMouseenter.emit(e);
5784
+ this.isHover.set(true);
5785
+ const { coordinate } = this.config();
5786
+ setMouseStyle('pointer', coordinate.container);
5787
+ }
5788
+ koMouseleave(e) {
5789
+ this.onMouseleave.emit(e);
5790
+ this.isHover.set(false);
5791
+ const { coordinate } = this.config();
5792
+ setMouseStyle('default', coordinate.container);
5793
+ }
5794
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableActionIcon, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5795
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableActionIcon, isStandalone: true, selector: "ai-table-action-icon", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onClick: "onClick", onMousemove: "onMousemove", onMouseenter: "onMouseenter", onMouseleave: "onMouseleave" }, ngImport: i0, template: `
5796
+ <ko-group
5797
+ [config]="groupConfig()"
5798
+ (koClick)="koClick($event)"
5799
+ (koMousemove)="koMousemove($event)"
5800
+ (koMouseenter)="koMouseenter($event)"
5801
+ (koMouseleave)="koMouseleave($event)"
5802
+ >
5803
+ <ko-rect [config]="squareShapeConfig()"></ko-rect>
5804
+ <ko-path [config]="iconConfig()"></ko-path>
5805
+ </ko-group>
5806
+ `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5807
+ }
5808
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableActionIcon, decorators: [{
5809
+ type: Component,
5810
+ args: [{
5811
+ selector: 'ai-table-action-icon',
5812
+ template: `
5813
+ <ko-group
5814
+ [config]="groupConfig()"
5815
+ (koClick)="koClick($event)"
5816
+ (koMousemove)="koMousemove($event)"
5817
+ (koMouseenter)="koMouseenter($event)"
5818
+ (koMouseleave)="koMouseleave($event)"
5819
+ >
5820
+ <ko-rect [config]="squareShapeConfig()"></ko-rect>
5821
+ <ko-path [config]="iconConfig()"></ko-path>
5822
+ </ko-group>
5823
+ `,
5824
+ standalone: true,
5825
+ imports: [KoContainer, KoShape],
5826
+ changeDetection: ChangeDetectionStrategy.OnPush
5827
+ }]
5828
+ }] });
5829
+
5830
+ class AITableCellAttachment {
5831
+ constructor() {
5832
+ this.config = input();
5833
+ this.attachments = computed(() => {
5834
+ const { render, aiTable, coordinate, field, recordId, readonly } = this.config();
5835
+ if (render) {
5836
+ const {} = aiTable;
5837
+ const { transformValue, references, columnWidth, rowHeight, style, zIndex } = render;
5838
+ if (!transformValue?.length) {
5839
+ return [];
5840
+ }
5841
+ const result = transformValue?.map((attachmentId, index) => {
5842
+ const itemWidth = AI_TABLE_FILE_ICON_SIZE + AI_TABLE_FIELD_ITEM_MARGIN_RIGHT;
5843
+ const currentX = AI_TABLE_CELL_PADDING + index * itemWidth + AI_TABLE_OFFSET;
5844
+ let currentY = (AI_TABLE_ROW_BLANK_HEIGHT - AI_TABLE_FILE_ICON_SIZE) / 2 + AI_TABLE_OFFSET;
5845
+ if (columnWidth != null) {
5846
+ // 当超出列宽时,不会渲染后续内容
5847
+ if (currentX >= columnWidth - AI_TABLE_ACTION_COMMON_SIZE - 2 * AI_TABLE_CELL_PADDING) {
5848
+ return null;
5849
+ }
5850
+ }
5851
+ const attachmentInfo = references.attachments[attachmentId];
5852
+ if (attachmentInfo) {
5853
+ const svgString = getFileThumbnailSvgString(attachmentInfo.addition.ext);
5854
+ const image = new Image();
5855
+ image.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
5856
+ return {
5857
+ // coordinate,
5858
+ // readonly,
5859
+ attachmentInfo,
5860
+ name: generateTargetName({
5861
+ targetName: AI_TABLE_CELL,
5862
+ fieldId: field._id,
5863
+ recordId,
5864
+ mouseStyle: readonly ? 'default' : 'pointer',
5865
+ source: attachmentInfo._id
5866
+ }),
5867
+ x: currentX,
5868
+ y: currentY,
5869
+ width: AI_TABLE_FILE_ICON_SIZE,
5870
+ height: AI_TABLE_FILE_ICON_SIZE,
5871
+ image,
5872
+ listening: true
5873
+ };
5874
+ }
5875
+ return null;
5876
+ }) || [];
5877
+ return result.filter((item) => !!item);
5878
+ }
5879
+ return [];
5880
+ });
5881
+ this.iconConfig = computed(() => {
5882
+ const { coordinate, render, field, recordId, readonly } = this.config();
5883
+ const offsetX = render.columnWidth - AI_TABLE_ACTION_COMMON_SIZE - AI_TABLE_ACTION_COMMON_RIGHT_PADDING;
5884
+ const offsetY = (coordinate.rowInitSize - AI_TABLE_ACTION_COMMON_SIZE) / 2;
5885
+ return {
5886
+ coordinate,
5887
+ readonly,
5888
+ name: generateTargetName({
5889
+ targetName: AI_TABLE_CELL,
5890
+ fieldId: field._id,
5891
+ recordId,
5892
+ source: AI_TABLE_CELL_ATTACHMENT_ADD,
5893
+ mouseStyle: readonly ? 'default' : 'pointer'
5894
+ }),
5895
+ x: offsetX,
5896
+ y: offsetY,
5897
+ data: AddOutlinedPath,
5898
+ fill: Colors.gray600,
5899
+ hoverFill: Colors.primary,
5900
+ backgroundWidth: AI_TABLE_ACTION_COMMON_SIZE,
5901
+ backgroundHeight: AI_TABLE_ACTION_COMMON_SIZE,
5902
+ cornerRadius: AI_TABLE_ACTION_COMMON_RADIUS,
5903
+ listening: true
5904
+ };
5905
+ });
5906
+ }
5907
+ static { this.fieldType = AITableFieldType.attachment; }
5908
+ addClick(e) {
5909
+ // e.event.cancelBubble = true;
5910
+ }
5911
+ attachmentClick(e) {
5912
+ // e.event.cancelBubble = true;
5913
+ }
5914
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableCellAttachment, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5915
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableCellAttachment, isStandalone: true, selector: "ai-table-attachments", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
5916
+ @for (attachment of attachments(); track attachment.attachmentInfo._id) {
5917
+ <ko-image [config]="attachment" (koClick)="attachmentClick($event)"></ko-image>
5918
+ }
5919
+ <ai-table-action-icon [config]="iconConfig()" (onClick)="addClick($event)"></ai-table-action-icon>
5920
+ `, isInline: true, dependencies: [{ kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableActionIcon, selector: "ai-table-action-icon", inputs: ["config"], outputs: ["onClick", "onMousemove", "onMouseenter", "onMouseleave"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5921
+ }
5922
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableCellAttachment, decorators: [{
5923
+ type: Component,
5924
+ args: [{
5925
+ selector: 'ai-table-attachments',
5926
+ template: `
5927
+ @for (attachment of attachments(); track attachment.attachmentInfo._id) {
5928
+ <ko-image [config]="attachment" (koClick)="attachmentClick($event)"></ko-image>
5929
+ }
5930
+ <ai-table-action-icon [config]="iconConfig()" (onClick)="addClick($event)"></ai-table-action-icon>
5931
+ `,
5932
+ standalone: true,
5933
+ imports: [KoContainer, KoShape, AITableActionIcon],
5934
+ changeDetection: ChangeDetectionStrategy.OnPush
5935
+ }]
5936
+ }] });
5937
+
5938
+ // TODO: components下的cells组件考虑移出 components ,这些组件都属于
5939
+
5940
+ var cellComponents = /*#__PURE__*/Object.freeze({
6371
5941
  __proto__: null,
6372
- apk: apk,
6373
- bak: bak,
6374
- bat: bat,
6375
- cs: cs,
6376
- css: css,
6377
- csv: csv,
6378
- defaultFile: defaultFile,
6379
- doc: doc,
6380
- exe: exe,
6381
- fla: fla,
6382
- html: html,
6383
- img: img,
6384
- ipa: ipa,
6385
- java: java,
6386
- js: js,
6387
- key: key,
6388
- mp3: mp3,
6389
- page: page,
6390
- pdf: pdf,
6391
- php: php,
6392
- ppt: ppt,
6393
- rar: rar,
6394
- snippet: snippet,
6395
- swf: swf,
6396
- ttf: ttf,
6397
- txt: txt,
6398
- video: video,
6399
- vss: vss,
6400
- xls: xls,
6401
- xsd: xsd,
6402
- zip: zip
5942
+ AITableCellAttachment: AITableCellAttachment,
5943
+ AITableCellLink: AITableCellLink
5944
+ });
5945
+
5946
+ const componentMap = {};
5947
+ Object.values(cellComponents).forEach((cellComponent) => {
5948
+ componentMap[cellComponent.fieldType] = cellComponent;
6403
5949
  });
6404
5950
 
6405
- function parseSVGToCanvasObjects(svgString) {
6406
- const parser = new DOMParser();
6407
- const svgDoc = parser.parseFromString(svgString, 'image/svg+xml');
6408
- const elements = svgDoc.querySelectorAll('path, polyline, polygon');
6409
- const canvasObjects = [];
6410
- elements.forEach((element) => {
6411
- let d;
6412
- if (element.tagName === 'path') {
6413
- d = element.getAttribute('d');
6414
- }
6415
- else if (element.tagName === 'polyline' || element.tagName === 'polygon') {
6416
- const points = element.getAttribute('points') || '';
6417
- const pointArray = points.split(/\s+|,/).filter(Boolean);
6418
- d = 'M' + pointArray[0] + ' ' + pointArray[1];
6419
- for (let i = 2; i < pointArray.length; i += 2) {
6420
- d += ' L' + pointArray[i] + ' ' + pointArray[i + 1];
5951
+ function getHoverCell(aiTable) {
5952
+ const pointPosition = aiTable.context.pointPosition();
5953
+ const { fieldId, recordId } = getDetailByTargetName(pointPosition.realTargetName) ?? {};
5954
+ if (!recordId || !fieldId) {
5955
+ return;
5956
+ }
5957
+ const record = aiTable.recordsMap()[recordId];
5958
+ const field = aiTable.fieldsMap()[fieldId];
5959
+ if (!record || !field || !recordId || !fieldId) {
5960
+ return;
5961
+ }
5962
+ const renderComponentDefinition = componentMap[field?.type];
5963
+ if (!renderComponentDefinition) {
5964
+ return;
5965
+ }
5966
+ return {
5967
+ field,
5968
+ recordId,
5969
+ fieldId,
5970
+ renderComponentDefinition
5971
+ };
5972
+ }
5973
+
5974
+ class AITableGridEventService {
5975
+ constructor() {
5976
+ this.dblClickEvent$ = new Subject();
5977
+ this.mousedownEvent$ = new Subject();
5978
+ this.mouseoverEvent$ = new Subject();
5979
+ this.globalMouseoverEvent$ = new Subject();
5980
+ this.globalMousedownEvent$ = new Subject();
5981
+ this.destroyRef = inject(DestroyRef);
5982
+ this.thyPopover = inject(ThyPopover);
5983
+ }
5984
+ initialize(aiTable, aiFieldRenderers) {
5985
+ this.aiTable = aiTable;
5986
+ this.aiFieldRenderers = aiFieldRenderers;
5987
+ }
5988
+ registerEvents(element) {
5989
+ fromEvent(element, 'dblclick', { passive: true })
5990
+ .pipe(takeUntilDestroyed(this.destroyRef))
5991
+ .subscribe((event) => {
5992
+ this.dblClickEvent$.next(event);
5993
+ });
5994
+ fromEvent(element, 'mouseover', { passive: true })
5995
+ .pipe(debounceTime(80), takeUntilDestroyed(this.destroyRef))
5996
+ .subscribe((event) => {
5997
+ this.mouseoverEvent$.next(event);
5998
+ });
5999
+ fromEvent(document, 'mouseover', { passive: true })
6000
+ .pipe(takeUntilDestroyed(this.destroyRef))
6001
+ .subscribe((event) => {
6002
+ this.globalMouseoverEvent$.next(event);
6003
+ });
6004
+ fromEvent(element, 'mousedown', { passive: true })
6005
+ .pipe(takeUntilDestroyed(this.destroyRef))
6006
+ .subscribe((event) => {
6007
+ this.mousedownEvent$.next(event);
6008
+ });
6009
+ fromEvent(document, 'mousedown', { passive: true })
6010
+ .pipe(takeUntilDestroyed(this.destroyRef))
6011
+ .subscribe((event) => {
6012
+ this.globalMousedownEvent$.next(event);
6013
+ });
6014
+ }
6015
+ getEditorComponent(type) {
6016
+ const filedRenderSchema = this.aiFieldRenderers && this.aiFieldRenderers[type];
6017
+ if (filedRenderSchema && filedRenderSchema.editor) {
6018
+ return {
6019
+ component: filedRenderSchema.editor,
6020
+ isInternalComponent: false
6021
+ };
6022
+ }
6023
+ return {
6024
+ component: GRID_CELL_EDITOR_MAP[type],
6025
+ isInternalComponent: true
6026
+ };
6027
+ }
6028
+ openEdit(cellDom) {
6029
+ const { x, y, width, height } = cellDom.getBoundingClientRect();
6030
+ const fieldId = cellDom.getAttribute('fieldId');
6031
+ const recordId = cellDom.getAttribute('recordId');
6032
+ const { component } = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
6033
+ const ref = this.thyPopover.open(component, {
6034
+ origin: cellDom,
6035
+ originPosition: {
6036
+ x: x - 1,
6037
+ y: y + 1,
6038
+ width: width + 2,
6039
+ height: height + 2
6040
+ },
6041
+ width: width + 1 + 'px',
6042
+ height: height + 2 + 'px',
6043
+ placement: 'top',
6044
+ offset: -(height + 4),
6045
+ minWidth: width,
6046
+ initialState: {
6047
+ fieldId: fieldId,
6048
+ recordId: recordId,
6049
+ aiTable: this.aiTable
6050
+ },
6051
+ panelClass: 'grid-cell-editor',
6052
+ outsideClosable: false,
6053
+ hasBackdrop: false,
6054
+ manualClosure: true,
6055
+ animationDisabled: true,
6056
+ autoAdaptive: true
6057
+ });
6058
+ return ref;
6059
+ }
6060
+ getOriginPosition(aiTable, options) {
6061
+ const { container, coordinate, recordId, fieldId, isHoverEdit } = options;
6062
+ const { scrollState } = aiTable.context;
6063
+ const { rowHeight, columnCount } = coordinate;
6064
+ const cell = [recordId, fieldId];
6065
+ const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, cell);
6066
+ const originX = coordinate.getColumnOffset(columnIndex);
6067
+ const originY = coordinate.getRowOffset(rowIndex);
6068
+ const columnWidth = coordinate.getColumnWidth(columnIndex);
6069
+ const { width: originWidth, offset: originOffset } = getCellHorizontalPosition({
6070
+ columnWidth,
6071
+ columnIndex,
6072
+ columnCount
6073
+ });
6074
+ const originRect = container.getBoundingClientRect();
6075
+ const isFrozenColumn = AITable.isFrozenColumn(aiTable, columnIndex);
6076
+ const scrollLeft = isFrozenColumn ? 0 : scrollState().scrollLeft;
6077
+ const scrollTop = scrollState().scrollTop;
6078
+ const originPosition = {
6079
+ x: originX + originOffset - scrollLeft + originRect.x,
6080
+ y: originY - scrollTop + originRect.y,
6081
+ width: originWidth,
6082
+ height: rowHeight
6083
+ };
6084
+ let x = originPosition.x + getEditorBoxOffset();
6085
+ let y = originPosition.y + getEditorBoxOffset();
6086
+ let width = getEditorSpace(originPosition.width);
6087
+ let height = getEditorSpace(originPosition.height);
6088
+ // hover 编辑组件无边框
6089
+ if (isHoverEdit) {
6090
+ x = originPosition.x + getHoverEditorBoxOffset();
6091
+ y = originPosition.y + getHoverEditorBoxOffset();
6092
+ width = getHoverEditorSpace(originPosition.width);
6093
+ height = getHoverEditorSpace(originPosition.height);
6094
+ }
6095
+ return {
6096
+ ...originPosition,
6097
+ x: x,
6098
+ y: y,
6099
+ width: width,
6100
+ height: height
6101
+ };
6102
+ }
6103
+ openCellEditor(aiTable, options) {
6104
+ const { container, recordId, fieldId, isHoverEdit, references } = options;
6105
+ const { component, isInternalComponent } = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
6106
+ const offsetOriginPosition = this.getOriginPosition(aiTable, options);
6107
+ this.cellEditorPopoverRef = this.thyPopover.open(component, {
6108
+ viewContainerRef: isInternalComponent ? undefined : options?.viewContainerRef,
6109
+ origin: container,
6110
+ originPosition: offsetOriginPosition,
6111
+ width: offsetOriginPosition.width + 'px',
6112
+ height: offsetOriginPosition.height + 'px',
6113
+ minWidth: offsetOriginPosition.width + 'px',
6114
+ placement: 'bottom',
6115
+ offset: -offsetOriginPosition.height,
6116
+ initialState: {
6117
+ fieldId: fieldId,
6118
+ recordId: recordId,
6119
+ references,
6120
+ aiTable: aiTable
6121
+ },
6122
+ panelClass: 'grid-cell-editor',
6123
+ outsideClosable: false,
6124
+ hasBackdrop: false,
6125
+ manualClosure: true,
6126
+ animationDisabled: true,
6127
+ autoAdaptive: true
6128
+ });
6129
+ if (this.cellEditorPopoverRef) {
6130
+ const wheelEvent = fromEvent(this.cellEditorPopoverRef.componentInstance.elementRef.nativeElement, 'wheel').subscribe((event) => {
6131
+ const field = aiTable.fieldsMap()[fieldId];
6132
+ if (field.type === AITableFieldType.text || field.type === AITableFieldType.richText) {
6133
+ return;
6134
+ }
6135
+ event.preventDefault();
6136
+ this.aiTable.context?.scrollAction({
6137
+ deltaX: event.deltaX,
6138
+ deltaY: event.deltaY,
6139
+ shiftKey: event.shiftKey,
6140
+ callback: () => {
6141
+ const originPosition = this.getOriginPosition(aiTable, options);
6142
+ const positionStrategy = this.cellEditorPopoverRef
6143
+ .getOverlayRef()
6144
+ .getConfig().positionStrategy;
6145
+ positionStrategy.setOrigin(originPosition);
6146
+ positionStrategy.apply();
6147
+ }
6148
+ });
6149
+ });
6150
+ this.cellEditorPopoverRef.afterClosed().subscribe(() => {
6151
+ wheelEvent.unsubscribe();
6152
+ this.cellEditorPopoverRef = null;
6153
+ });
6154
+ this.cellEditorPopoverRef.componentInstance.updateFieldValue.subscribe((value) => {
6155
+ options.updateFieldValue(value);
6156
+ });
6157
+ }
6158
+ return this.cellEditorPopoverRef;
6159
+ }
6160
+ closeCellEditor() {
6161
+ if (this.cellEditorPopoverRef) {
6162
+ this.cellEditorPopoverRef.close();
6163
+ this.cellEditorPopoverRef = null;
6164
+ }
6165
+ }
6166
+ getCurrentEditCell() {
6167
+ if (this.cellEditorPopoverRef) {
6168
+ const recordId = this.cellEditorPopoverRef.componentInstance?.recordId;
6169
+ const fieldId = this.cellEditorPopoverRef.componentInstance?.fieldId;
6170
+ if (recordId && fieldId) {
6171
+ return {
6172
+ recordId,
6173
+ fieldId
6174
+ };
6175
+ }
6176
+ return null;
6177
+ }
6178
+ return null;
6179
+ }
6180
+ openContextMenu(aiTable, options) {
6181
+ const { origin, position, menuItems, targetName, viewContainerRef } = options;
6182
+ const ref = this.thyPopover.open(AITableContextMenu, {
6183
+ origin: origin,
6184
+ originPosition: position,
6185
+ placement: 'bottomLeft',
6186
+ insideClosable: true,
6187
+ viewContainerRef,
6188
+ initialState: {
6189
+ aiTable,
6190
+ menuItems,
6191
+ targetName,
6192
+ position
6193
+ }
6194
+ });
6195
+ return ref;
6196
+ }
6197
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6198
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService }); }
6199
+ }
6200
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, decorators: [{
6201
+ type: Injectable
6202
+ }] });
6203
+
6204
+ class AITableGridBase {
6205
+ constructor() {
6206
+ this.aiRecords = model.required();
6207
+ this.aiFields = model.required();
6208
+ this.aiContextMenuItems = input([]);
6209
+ this.aiFieldConfig = input();
6210
+ this.aiReadonly = input();
6211
+ this.aiPlugins = input();
6212
+ this.aiReferences = input.required();
6213
+ this.aiBuildRenderDataFn = input();
6214
+ this.aiKeywords = input();
6215
+ this.AITableFieldType = AITableFieldType;
6216
+ this.AITableSelectOptionStyle = AITableSelectOptionStyle;
6217
+ this.isSelectedAll = computed(() => {
6218
+ return this.aiTable.selection().selectedRecords.size === this.aiRecords().length;
6219
+ });
6220
+ this.aiTableInitialized = output();
6221
+ this.aiAddRecord = output();
6222
+ this.aiAddField = output();
6223
+ this.aiMoveField = output();
6224
+ this.aiUpdateFieldValue = output();
6225
+ this.aiSetField = output();
6226
+ this.aiClick = output();
6227
+ this.aiDbClick = output();
6228
+ this.fieldMenus = computed(() => {
6229
+ return this.aiFieldConfig()?.fieldMenus || [];
6230
+ });
6231
+ this.gridData = computed(() => {
6232
+ if (this.aiBuildRenderDataFn && this.aiBuildRenderDataFn() && this.aiTable) {
6233
+ return this.aiBuildRenderDataFn()(this.aiTable);
6234
+ }
6235
+ return {
6236
+ records: this.aiRecords(),
6237
+ fields: this.aiFields()
6238
+ };
6239
+ });
6240
+ this.ngZone = inject(NgZone);
6241
+ this.elementRef = inject(ElementRef);
6242
+ this.destroyRef = inject(DestroyRef);
6243
+ this.aiTableGridFieldService = inject(AITableGridFieldService);
6244
+ this.aiTableGridEventService = inject(AITableGridEventService);
6245
+ this.aiTableGridSelectionService = inject(AITableGridSelectionService);
6246
+ }
6247
+ ngOnInit() {
6248
+ this.initAITable();
6249
+ this.initService();
6250
+ }
6251
+ initAITable() {
6252
+ this.aiTable = createAITable(this.aiRecords, this.aiFields, this.gridData);
6253
+ this.aiPlugins()?.forEach((plugin) => {
6254
+ this.aiTable = plugin(this.aiTable);
6255
+ });
6256
+ this.aiTableInitialized.emit(this.aiTable);
6257
+ }
6258
+ initService() {
6259
+ this.aiTableGridEventService.initialize(this.aiTable, this.aiFieldConfig()?.fieldRenderers);
6260
+ this.aiTableGridSelectionService.initialize(this.aiTable);
6261
+ this.aiTableGridEventService.registerEvents(this.elementRef.nativeElement);
6262
+ this.aiTableGridFieldService.initAIFieldConfig(this.aiFieldConfig());
6263
+ AI_TABLE_GRID_FIELD_SERVICE_MAP.set(this.aiTable, this.aiTableGridFieldService);
6264
+ }
6265
+ addRecord() {
6266
+ const records = this.aiRecords();
6267
+ const recordCount = records.length;
6268
+ this.aiAddRecord.emit({
6269
+ originId: recordCount > 0 ? records[records.length - 1]._id : ''
6270
+ });
6271
+ }
6272
+ selectRecord(recordId) {
6273
+ this.aiTableGridSelectionService.selectRecord(recordId);
6274
+ }
6275
+ toggleSelectAll(checked) {
6276
+ this.aiTableGridSelectionService.toggleSelectAll(checked);
6277
+ }
6278
+ addField(gridColumnBlank, position) {
6279
+ const field = createDefaultField(this.aiTable, AITableFieldType.text);
6280
+ const popoverRef = this.aiTableGridFieldService.editFieldProperty(this.aiTable, {
6281
+ field,
6282
+ isUpdate: false,
6283
+ origin: gridColumnBlank,
6284
+ position
6285
+ });
6286
+ if (popoverRef && !this.aiFieldConfig()?.fieldSettingComponent) {
6287
+ popoverRef.componentInstance.addField.subscribe((defaultValue) => {
6288
+ const fields = this.gridData().fields;
6289
+ const fieldCount = fields.length;
6290
+ this.aiAddField.emit({
6291
+ originId: fieldCount > 0 ? fields[fields.length - 1]._id : '',
6292
+ defaultValue
6293
+ });
6294
+ });
6295
+ }
6296
+ }
6297
+ subscribeEvents() {
6298
+ this.ngZone.runOutsideAngular(() => {
6299
+ this.aiTableGridEventService.dblClickEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
6300
+ this.dblClick(event);
6301
+ });
6302
+ this.aiTableGridEventService.mousedownEvent$
6303
+ .pipe(mergeWith(this.aiTableGridEventService.globalMousedownEvent$), takeUntilDestroyed(this.destroyRef))
6304
+ .subscribe((event) => {
6305
+ this.aiTableGridSelectionService.updateSelect(event);
6306
+ });
6307
+ this.aiTableGridEventService.mouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
6308
+ this.mouseoverHandle(event);
6309
+ });
6310
+ this.aiTableGridEventService.globalMouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
6311
+ this.closeHoverCellEditor(event);
6312
+ });
6313
+ });
6314
+ }
6315
+ dblClick(event) {
6316
+ const cellDom = event.target.closest('.grid-cell');
6317
+ const type = cellDom && cellDom.getAttribute('type');
6318
+ if (type && DBL_CLICK_EDIT_TYPE.includes(type)) {
6319
+ this.aiTableGridEventService.openEdit(cellDom);
6320
+ }
6321
+ }
6322
+ mouseoverHandle(event) {
6323
+ if (this.mouseoverRef) {
6324
+ this.mouseoverRef?.close();
6325
+ }
6326
+ const cellDom = event.target.closest('.grid-cell');
6327
+ const type = cellDom && cellDom.getAttribute('type');
6328
+ if (type && MOUSEOVER_EDIT_TYPE.includes(type)) {
6329
+ this.mouseoverRef = this.aiTableGridEventService.openEdit(cellDom);
6330
+ }
6331
+ }
6332
+ closeHoverCellEditor(e) {
6333
+ if (this.mouseoverRef) {
6334
+ const hasGrid = e.target && e.target.closest('.ai-table-grid');
6335
+ const hasCellEditor = e.target && e.target.closest('.grid-cell-editor');
6336
+ if (!hasGrid && !hasCellEditor) {
6337
+ this.mouseoverRef.close();
6421
6338
  }
6422
- if (element.tagName === 'polygon') {
6423
- d += ' Z';
6339
+ }
6340
+ }
6341
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6342
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableGridBase, isStandalone: true, selector: "ai-table-grid-base", inputs: { aiRecords: { classPropertyName: "aiRecords", publicName: "aiRecords", isSignal: true, isRequired: true, transformFunction: null }, aiFields: { classPropertyName: "aiFields", publicName: "aiFields", isSignal: true, isRequired: true, transformFunction: null }, aiContextMenuItems: { classPropertyName: "aiContextMenuItems", publicName: "aiContextMenuItems", isSignal: true, isRequired: false, transformFunction: null }, aiFieldConfig: { classPropertyName: "aiFieldConfig", publicName: "aiFieldConfig", isSignal: true, isRequired: false, transformFunction: null }, aiReadonly: { classPropertyName: "aiReadonly", publicName: "aiReadonly", isSignal: true, isRequired: false, transformFunction: null }, aiPlugins: { classPropertyName: "aiPlugins", publicName: "aiPlugins", isSignal: true, isRequired: false, transformFunction: null }, aiReferences: { classPropertyName: "aiReferences", publicName: "aiReferences", isSignal: true, isRequired: true, transformFunction: null }, aiBuildRenderDataFn: { classPropertyName: "aiBuildRenderDataFn", publicName: "aiBuildRenderDataFn", isSignal: true, isRequired: false, transformFunction: null }, aiKeywords: { classPropertyName: "aiKeywords", publicName: "aiKeywords", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiRecords: "aiRecordsChange", aiFields: "aiFieldsChange", aiTableInitialized: "aiTableInitialized", aiAddRecord: "aiAddRecord", aiAddField: "aiAddField", aiMoveField: "aiMoveField", aiUpdateFieldValue: "aiUpdateFieldValue", aiSetField: "aiSetField", aiClick: "aiClick", aiDbClick: "aiDbClick" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6343
+ }
6344
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, decorators: [{
6345
+ type: Component,
6346
+ args: [{
6347
+ selector: 'ai-table-grid-base',
6348
+ template: '',
6349
+ standalone: true,
6350
+ changeDetection: ChangeDetectionStrategy.OnPush
6351
+ }]
6352
+ }] });
6353
+
6354
+ class AITableDomGrid extends AITableGridBase {
6355
+ ngOnInit() {
6356
+ super.ngOnInit();
6357
+ this.subscribeEvents();
6358
+ }
6359
+ openFieldMenu(e, field, fieldAction) {
6360
+ const moreBtn = e.target.closest('.grid-field-action');
6361
+ this.aiTableGridFieldService.openFieldMenu(this.aiTable, {
6362
+ origin: moreBtn,
6363
+ editOrigin: fieldAction,
6364
+ fieldId: field._id,
6365
+ fieldMenus: this.fieldMenus()
6366
+ });
6367
+ }
6368
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
6369
+ 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 }); }
6370
+ }
6371
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, decorators: [{
6372
+ type: Component,
6373
+ args: [{ selector: 'ai-table-dom-grid', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
6374
+ class: 'ai-table-grid ai-table-dom-grid'
6375
+ }, imports: [
6376
+ NgClass,
6377
+ NgComponentOutlet,
6378
+ CommonModule,
6379
+ FormsModule,
6380
+ SelectOptionPipe,
6381
+ SelectOptionsPipe,
6382
+ ThyTag,
6383
+ ThyPopoverModule,
6384
+ ThyIcon,
6385
+ ThyRate,
6386
+ ThyProgress,
6387
+ AITableFieldSetting,
6388
+ ThyDatePickerFormatPipe,
6389
+ ThyFlexibleText,
6390
+ ThyStopPropagationDirective,
6391
+ AITableFieldMenu,
6392
+ ThyAction,
6393
+ ThyDropdownDirective,
6394
+ ThyDropdownMenuComponent,
6395
+ ThyCheckboxModule,
6396
+ ProgressEditorComponent,
6397
+ ThyAvatarModule,
6398
+ NgTemplateOutlet,
6399
+ IsSelectRecordPipe,
6400
+ ProgressEditorComponent,
6401
+ SelectOptionComponent,
6402
+ UserPipe,
6403
+ SelectSettingPipe,
6404
+ MemberSettingPipe
6405
+ ], 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" }]
6406
+ }] });
6407
+
6408
+ class AITableIcon {
6409
+ constructor() {
6410
+ this.config = input.required();
6411
+ this.groupConfig = computed(() => {
6412
+ const { x, y, listening } = this.config();
6413
+ return { x, y, listening };
6414
+ });
6415
+ this.squareShapeConfig = computed(() => {
6416
+ const { name, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, strokeWidth = 1, background, cornerRadius, opacity } = this.config();
6417
+ return {
6418
+ name,
6419
+ width: backgroundWidth || size,
6420
+ height: backgroundHeight || size,
6421
+ strokeWidth: strokeWidth,
6422
+ fill: background || Colors.transparent,
6423
+ cornerRadius,
6424
+ opacity
6425
+ };
6426
+ });
6427
+ this.iconConfig = computed(() => {
6428
+ const { type, data, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, stroke, strokeWidth = 1, scaleX, scaleY, offsetX, offsetY, rotation, fill = Colors.gray600, transformsEnabled = 'position' } = this.config();
6429
+ let pathData = data;
6430
+ switch (type) {
6431
+ case AITableCheckType.checked:
6432
+ pathData = Check;
6433
+ break;
6434
+ case AITableCheckType.unchecked:
6435
+ pathData = Unchecked;
6436
+ break;
6424
6437
  }
6425
- }
6426
- const fill = element.getAttribute('fill') || 'black';
6427
- const stroke = 'none';
6428
- const strokeWidth = element.getAttribute('stroke-width') || 0;
6429
- const opacity = parseFloat(element?.getAttribute('opacity') || '1');
6430
- const fillRule = element.getAttribute('fill-rule') || 'nonzero';
6431
- if (d) {
6432
- canvasObjects.push({
6433
- d,
6438
+ return {
6439
+ x: backgroundWidth && (backgroundWidth - size * (scaleX || 1)) / 2,
6440
+ y: backgroundHeight && (backgroundHeight - size * (scaleY || 1)) / 2,
6441
+ data: pathData,
6442
+ width: size,
6443
+ height: size,
6434
6444
  fill,
6445
+ offsetX,
6446
+ offsetY,
6447
+ scaleX,
6448
+ scaleY,
6449
+ rotation,
6435
6450
  stroke,
6436
6451
  strokeWidth,
6437
- opacity,
6438
- fillRule: fillRule
6452
+ transformsEnabled,
6453
+ perfectDrawEnabled: false,
6454
+ listening: false
6455
+ };
6456
+ });
6457
+ }
6458
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6459
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableIcon, isStandalone: true, selector: "ai-table-icon", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
6460
+ <ko-group [config]="groupConfig()">
6461
+ <ko-rect [config]="squareShapeConfig()"></ko-rect>
6462
+ <ko-path [config]="iconConfig()"></ko-path>
6463
+ </ko-group>
6464
+ `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6465
+ }
6466
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, decorators: [{
6467
+ type: Component,
6468
+ args: [{
6469
+ selector: 'ai-table-icon',
6470
+ template: `
6471
+ <ko-group [config]="groupConfig()">
6472
+ <ko-rect [config]="squareShapeConfig()"></ko-rect>
6473
+ <ko-path [config]="iconConfig()"></ko-path>
6474
+ </ko-group>
6475
+ `,
6476
+ standalone: true,
6477
+ imports: [KoContainer, KoShape],
6478
+ changeDetection: ChangeDetectionStrategy.OnPush
6479
+ }]
6480
+ }] });
6481
+
6482
+ class AITableAddField {
6483
+ constructor() {
6484
+ this.config = input.required();
6485
+ this.btnWidth = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
6486
+ this.x = computed(() => {
6487
+ const lastColumnWidth = this.config().coordinate.getColumnWidth(this.config().columnStopIndex);
6488
+ const lastColumnOffset = this.config().coordinate.getColumnOffset(this.config().columnStopIndex);
6489
+ return lastColumnWidth + lastColumnOffset;
6490
+ });
6491
+ this.rectConfig = computed(() => {
6492
+ const { pointPosition: { targetName }, readonly } = this.config();
6493
+ const fill = targetName === AI_TABLE_FIELD_ADD_BUTTON ? Colors.gray80 : Colors.white;
6494
+ return {
6495
+ name: generateTargetName({
6496
+ targetName: AI_TABLE_FIELD_ADD_BUTTON,
6497
+ fieldId: this.config().fields[this.config().columnStopIndex]._id,
6498
+ mouseStyle: readonly ? 'default' : 'pointer'
6499
+ }),
6500
+ x: AI_TABLE_OFFSET,
6501
+ y: AI_TABLE_OFFSET,
6502
+ width: this.config().coordinate.containerWidth - this.x() < this.btnWidth
6503
+ ? this.btnWidth
6504
+ : this.config().coordinate.containerWidth - this.x(),
6505
+ height: this.config().coordinate.rowInitSize,
6506
+ stroke: Colors.gray200,
6507
+ strokeWidth: 1,
6508
+ listening: true,
6509
+ fill
6510
+ };
6511
+ });
6512
+ this.addIconConfig = computed(() => {
6513
+ const { readonly } = this.config();
6514
+ const offsetY = (this.config().coordinate.rowInitSize - AI_TABLE_ICON_COMMON_SIZE) / 2;
6515
+ return {
6516
+ x: AI_TABLE_CELL_PADDING,
6517
+ y: offsetY,
6518
+ data: AddOutlinedPath,
6519
+ fill: Colors.gray600,
6520
+ listening: false,
6521
+ visible: isNil(readonly) ? true : !readonly
6522
+ };
6523
+ });
6524
+ }
6525
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6526
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableAddField, isStandalone: true, selector: "ai-table-add-field", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
6527
+ <ko-group [config]="{ x: x() }">
6528
+ <ko-group>
6529
+ <ko-rect [config]="rectConfig()"></ko-rect>
6530
+ </ko-group>
6531
+ <ko-group>
6532
+ @if (addIconConfig().visible) {
6533
+ <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
6534
+ }
6535
+ </ko-group>
6536
+ </ko-group>
6537
+ `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { 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: AITableIcon, selector: "ai-table-icon", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6538
+ }
6539
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, decorators: [{
6540
+ type: Component,
6541
+ args: [{
6542
+ selector: 'ai-table-add-field',
6543
+ template: `
6544
+ <ko-group [config]="{ x: x() }">
6545
+ <ko-group>
6546
+ <ko-rect [config]="rectConfig()"></ko-rect>
6547
+ </ko-group>
6548
+ <ko-group>
6549
+ @if (addIconConfig().visible) {
6550
+ <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
6551
+ }
6552
+ </ko-group>
6553
+ </ko-group>
6554
+ `,
6555
+ standalone: true,
6556
+ imports: [KoContainer, KoShape, AITableIcon],
6557
+ changeDetection: ChangeDetectionStrategy.OnPush
6558
+ }]
6559
+ }] });
6560
+
6561
+ /**
6562
+ * 用于处理表格行或单元格的布局和绘制。
6563
+ * 它提供了基本的布局信息(如位置、大小等),并定义了常用的绘图方法(如渲染缩进区域、添加新字段的空白区域等)。
6564
+ * 该类继承自 Drawer,并被其他更具体的布局类(如 RecordRowLayout)扩展和使用
6565
+ */
6566
+ class Layout extends Drawer {
6567
+ constructor() {
6568
+ super(...arguments);
6569
+ // 定义当前单元格或行的位置
6570
+ this.x = 0;
6571
+ this.y = 0;
6572
+ // 行高
6573
+ this.rowHeight = 0;
6574
+ // 列宽
6575
+ this.columnWidth = 0;
6576
+ // 行索引
6577
+ this.rowIndex = 0;
6578
+ // 列索引
6579
+ this.columnIndex = 0;
6580
+ // 列数
6581
+ this.columnCount = 0;
6582
+ this.containerWidth = 0;
6583
+ }
6584
+ // 用于初始化或重置布局的基本属性。这个方法通常在每次渲染新的一行或单元格时调用,确保布局信息是最新的
6585
+ init({ x, y, rowIndex, columnIndex, rowHeight, columnWidth, columnCount, containerWidth }) {
6586
+ this.x = x;
6587
+ this.y = y;
6588
+ this.rowIndex = rowIndex;
6589
+ this.columnIndex = columnIndex;
6590
+ this.rowHeight = rowHeight;
6591
+ this.columnWidth = columnWidth;
6592
+ this.columnCount = columnCount;
6593
+ this.containerWidth = containerWidth;
6594
+ }
6595
+ // 当前单元格是否是行的第一列
6596
+ get isFirst() {
6597
+ return this.columnIndex === 0;
6598
+ }
6599
+ // 当前单元格是否是行的最后一列
6600
+ get isLast() {
6601
+ return this.columnIndex === this.columnCount - 1;
6602
+ }
6603
+ renderAddFieldBlank({ isHoverRow, isCheckedRow }) {
6604
+ const rowHeight = this.rowHeight;
6605
+ const fill = isCheckedRow ? this.colors.itemActiveBgColor : isHoverRow ? this.colors.gray80 : this.colors.transparent;
6606
+ const addFieldBlankX = this.x + this.columnWidth + AI_TABLE_OFFSET;
6607
+ this.rect({
6608
+ x: addFieldBlankX,
6609
+ y: this.y + AI_TABLE_OFFSET,
6610
+ width: this.containerWidth - addFieldBlankX < AI_TABLE_FIELD_ADD_BUTTON_WIDTH
6611
+ ? AI_TABLE_FIELD_ADD_BUTTON_WIDTH
6612
+ : this.containerWidth - addFieldBlankX,
6613
+ height: rowHeight,
6614
+ fill
6615
+ });
6616
+ }
6617
+ }
6618
+
6619
+ class AddRowLayout extends Layout {
6620
+ renderAddFieldBlank({ isHoverRow, isCheckedRow }) {
6621
+ super.renderAddFieldBlank({ isHoverRow, isCheckedRow });
6622
+ const rowHeight = this.rowHeight;
6623
+ const defaultWidth = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
6624
+ const width = this.containerWidth - this.x < defaultWidth ? defaultWidth : this.containerWidth - this.x;
6625
+ this.line({
6626
+ x: this.x + this.columnWidth,
6627
+ y: this.y,
6628
+ points: [0, rowHeight, width, rowHeight],
6629
+ stroke: this.colors.gray200
6630
+ });
6631
+ }
6632
+ renderCell({ width, isHoverRow }) {
6633
+ const x = this.x;
6634
+ const y = this.y;
6635
+ const rowHeight = this.rowHeight;
6636
+ const fill = isHoverRow ? this.colors.gray80 : this.colors.transparent;
6637
+ this.rect({
6638
+ x,
6639
+ y: y + AI_TABLE_OFFSET,
6640
+ width: width,
6641
+ height: rowHeight,
6642
+ fill
6643
+ });
6644
+ this.line({
6645
+ x,
6646
+ y: y + rowHeight,
6647
+ points: [0, 0, width, 0],
6648
+ stroke: this.colors.gray200
6649
+ });
6650
+ }
6651
+ renderFirstCell({ isHoverRow }) {
6652
+ if (!this.isFirst)
6653
+ return;
6654
+ const y = this.y;
6655
+ const rowHeight = this.rowHeight;
6656
+ const columnWidth = this.columnWidth;
6657
+ const frozenOffset = AI_TABLE_OFFSET;
6658
+ const fill = isHoverRow ? this.colors.gray80 : this.colors.transparent;
6659
+ this.rect({
6660
+ x: frozenOffset,
6661
+ y: y + AI_TABLE_OFFSET,
6662
+ width: columnWidth + AI_TABLE_ROW_HEAD_WIDTH - frozenOffset + 1,
6663
+ height: rowHeight,
6664
+ fill
6665
+ });
6666
+ this.line({
6667
+ x: frozenOffset,
6668
+ y,
6669
+ points: [0, rowHeight, columnWidth + AI_TABLE_ROW_HEAD_WIDTH - frozenOffset + 1, rowHeight],
6670
+ stroke: this.colors.gray200
6671
+ });
6672
+ this.path({
6673
+ x: AI_TABLE_CELL_PADDING,
6674
+ y: y + (rowHeight - AI_TABLE_ICON_COMMON_SIZE) / 2 - AI_TABLE_OFFSET,
6675
+ data: AddOutlinedPath,
6676
+ size: AI_TABLE_ROW_HEAD_SIZE,
6677
+ fill: this.colors.gray600
6678
+ });
6679
+ }
6680
+ renderLastCell({ isHoverRow, isCheckedRow }) {
6681
+ if (!this.isLast)
6682
+ return;
6683
+ const width = this.columnWidth;
6684
+ if (!this.isFirst) {
6685
+ this.renderCell({
6686
+ width,
6687
+ isHoverRow
6439
6688
  });
6440
6689
  }
6441
- });
6442
- return canvasObjects;
6443
- }
6444
- const FileIcons = (() => {
6445
- const result = {};
6446
- Object.entries(fileIcons).forEach((fileIcon) => {
6447
- result[fileIcon[0]] = parseSVGToCanvasObjects(fileIcon[1]);
6448
- });
6449
- return result;
6450
- })();
6451
-
6452
- function getFileThumbnailName(ext) {
6453
- let result = 'defaultFile';
6454
- switch (ext) {
6455
- case 'doc':
6456
- case 'docx':
6457
- result = 'doc';
6458
- break;
6459
- case 'ppt':
6460
- case 'pptx':
6461
- result = 'ppt';
6462
- break;
6463
- case 'xls':
6464
- case 'xlsx':
6465
- result = 'xls';
6466
- break;
6467
- case 'css':
6468
- case 'scss':
6469
- case 'sass':
6470
- case 'less':
6471
- result = 'css';
6472
- break;
6473
- case 'png':
6474
- case 'jpeg':
6475
- case 'jpg':
6476
- case 'gif':
6477
- case 'bmp':
6478
- case 'svg':
6479
- result = 'img';
6480
- break;
6481
- case 'mp4':
6482
- case 'mkv':
6483
- case 'webm':
6484
- case 'mov':
6485
- case 'flv':
6486
- case '3gp':
6487
- case 'mpv':
6488
- case 'avi':
6489
- case 'mpeg':
6490
- case 'wmv':
6491
- result = 'video';
6492
- break;
6493
- case 'mp3':
6494
- case 'wma':
6495
- case 'wav':
6496
- case 'ape':
6497
- case 'flac':
6498
- case 'ogg':
6499
- case 'm4r':
6500
- case 'm4a':
6501
- result = 'mp3';
6502
- break;
6503
- case 'pdf':
6504
- case 'txt':
6505
- case 'apk':
6506
- case 'bak':
6507
- case 'cs':
6508
- case 'csv':
6509
- case 'exe':
6510
- case 'fla':
6511
- case 'html':
6512
- case 'ipa':
6513
- case 'java':
6514
- case 'js':
6515
- case 'php':
6516
- case 'rar':
6517
- case 'swf':
6518
- case 'ttf':
6519
- case 'vss':
6520
- case 'xsd':
6521
- case 'zip':
6522
- case 'youdaonote':
6523
- case 'evernote':
6524
- case 'yinxiang':
6525
- case 'quip':
6526
- case 'onenote':
6527
- case 'onedrive':
6528
- case 'box':
6529
- case 'shimo':
6530
- case 'processon':
6531
- result = ext;
6532
- break;
6533
- default:
6534
- result = 'defaultFile';
6535
- break;
6690
+ this.renderAddFieldBlank({ isHoverRow, isCheckedRow });
6536
6691
  }
6537
- return result;
6538
- }
6539
- function getFileThumbnailSvgString(ext) {
6540
- let result = 'defaultFile';
6541
- switch (ext) {
6542
- case 'doc':
6543
- case 'docx':
6544
- result = doc;
6545
- break;
6546
- case 'ppt':
6547
- case 'pptx':
6548
- result = ppt;
6549
- break;
6550
- case 'xls':
6551
- case 'xlsx':
6552
- result = xls;
6553
- break;
6554
- case 'css':
6555
- case 'scss':
6556
- case 'sass':
6557
- case 'less':
6558
- result = css;
6559
- break;
6560
- case 'png':
6561
- case 'jpeg':
6562
- case 'jpg':
6563
- case 'gif':
6564
- case 'bmp':
6565
- case 'svg':
6566
- result = img;
6567
- break;
6568
- case 'mp4':
6569
- case 'mkv':
6570
- case 'webm':
6571
- case 'mov':
6572
- case 'flv':
6573
- case '3gp':
6574
- case 'mpv':
6575
- case 'avi':
6576
- case 'mpeg':
6577
- case 'wmv':
6578
- result = video;
6579
- break;
6580
- case 'mp3':
6581
- case 'wma':
6582
- case 'wav':
6583
- case 'ape':
6584
- case 'flac':
6585
- case 'ogg':
6586
- case 'm4r':
6587
- case 'm4a':
6588
- result = mp3;
6589
- break;
6590
- case 'pdf':
6591
- result = pdf;
6592
- break;
6593
- case 'txt':
6594
- result = txt;
6595
- break;
6596
- case 'apk':
6597
- result = apk;
6598
- break;
6599
- case 'bak':
6600
- result = apk;
6601
- break;
6602
- case 'cs':
6603
- result = cs;
6604
- break;
6605
- case 'csv':
6606
- result = csv;
6607
- break;
6608
- case 'exe':
6609
- result = exe;
6610
- break;
6611
- case 'fla':
6612
- result = fla;
6613
- break;
6614
- case 'html':
6615
- result = html;
6616
- break;
6617
- case 'ipa':
6618
- result = ipa;
6619
- break;
6620
- case 'java':
6621
- result = java;
6622
- break;
6623
- case 'js':
6624
- result = js;
6625
- break;
6626
- case 'php':
6627
- result = php;
6628
- break;
6629
- case 'rar':
6630
- result = rar;
6631
- break;
6632
- case 'swf':
6633
- result = swf;
6634
- break;
6635
- case 'ttf':
6636
- result = ttf;
6637
- break;
6638
- case 'vss':
6639
- result = vss;
6640
- break;
6641
- case 'xsd':
6642
- result = xsd;
6643
- break;
6644
- case 'zip':
6645
- result = zip;
6646
- break;
6647
- default:
6648
- result = defaultFile;
6649
- break;
6692
+ renderCommonCell({ isHoverRow }) {
6693
+ if (this.isFirst || this.isLast)
6694
+ return;
6695
+ this.renderCell({
6696
+ width: this.columnWidth,
6697
+ isHoverRow
6698
+ });
6699
+ }
6700
+ render({ isHoverRow, isCheckedRow }) {
6701
+ this.renderFirstCell({
6702
+ isHoverRow
6703
+ });
6704
+ this.renderCommonCell({
6705
+ isHoverRow
6706
+ });
6707
+ this.renderLastCell({
6708
+ isHoverRow,
6709
+ isCheckedRow
6710
+ });
6650
6711
  }
6651
- return result;
6652
- }
6653
- function getFileCanvasPaths(ext) {
6654
- const fileThumbnailName = getFileThumbnailName(ext);
6655
- return FileIcons[fileThumbnailName];
6656
6712
  }
6713
+ const addRowLayout = new AddRowLayout();
6657
6714
 
6658
6715
  /**
6659
6716
  * 处理和渲染表格单元格的内容
@@ -7265,15 +7322,12 @@ class CellDrawer extends Drawer {
7265
7322
  }
7266
7323
  renderCellAttachment(render, ctx) {
7267
7324
  const { references, x, y, field, transformValue: _cellValue, rowHeight, columnWidth, isActive } = render;
7268
- const cellValue = _cellValue;
7269
- if (!cellValue?.length || !references) {
7270
- return;
7271
- }
7325
+ const cellValue = _cellValue || [];
7272
7326
  const fileIconSize = AI_TABLE_FILE_ICON_SIZE;
7273
7327
  const itemHeight = AI_TABLE_FILE_ICON_ITEM_HEIGHT;
7274
7328
  const isOperating = isActive;
7275
7329
  let currentX = AI_TABLE_CELL_PADDING;
7276
- let currentY = (AI_TABLE_ROW_BLANK_HEIGHT - fileIconSize) / 2;
7330
+ let currentY = (AI_TABLE_ROW_BLANK_HEIGHT - itemHeight) / 2;
7277
7331
  const itemOtherWidth = fileIconSize + AI_TABLE_FIELD_ITEM_MARGIN_RIGHT;
7278
7332
  const maxHeight = isActive ? 130 - AI_TABLE_CELL_MULTI_PADDING_TOP : rowHeight - AI_TABLE_CELL_MULTI_PADDING_TOP;
7279
7333
  const maxTextWidth = isOperating
@@ -7282,7 +7336,7 @@ class CellDrawer extends Drawer {
7282
7336
  const listCount = cellValue.length;
7283
7337
  let isOverflow = false;
7284
7338
  for (let index = 0; index < listCount; index++) {
7285
- const attachmentInfo = references.attachments[cellValue[index]];
7339
+ const attachmentInfo = references?.attachments[cellValue[index]];
7286
7340
  if (!attachmentInfo)
7287
7341
  continue;
7288
7342
  const { title, addition } = attachmentInfo;
@@ -8369,7 +8423,7 @@ class AITableHoverCells {
8369
8423
  };
8370
8424
  });
8371
8425
  this.hoverCellConfig = computed(() => {
8372
- const { aiTable, coordinate } = this.config();
8426
+ const { aiTable, coordinate, references, readonly } = this.config();
8373
8427
  const pointPosition = aiTable.context.pointPosition();
8374
8428
  const hoverCell = this.hoverCell();
8375
8429
  if (!hoverCell) {
@@ -8377,10 +8431,7 @@ class AITableHoverCells {
8377
8431
  }
8378
8432
  const { field, recordId, fieldId, renderComponentDefinition } = hoverCell;
8379
8433
  const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, field._id]);
8380
- const transformValue = transformCellValue(aiTable, field, cellValue) || {};
8381
- if (Object.keys(transformValue).length === 0) {
8382
- return;
8383
- }
8434
+ const transformValue = transformCellValue(aiTable, field, cellValue);
8384
8435
  const { rowHeight, columnCount, rowCount } = coordinate;
8385
8436
  const columnIndex = pointPosition.columnIndex;
8386
8437
  const rowIndex = pointPosition.rowIndex;
@@ -8402,10 +8453,12 @@ class AITableHoverCells {
8402
8453
  const renderY = 0 - AI_TABLE_OFFSET * 2;
8403
8454
  const result = {
8404
8455
  field,
8456
+ recordId,
8405
8457
  aiTable,
8406
8458
  coordinate,
8407
8459
  x,
8408
8460
  y,
8461
+ readonly,
8409
8462
  render: {
8410
8463
  aiTable,
8411
8464
  recordId,
@@ -8417,7 +8470,8 @@ class AITableHoverCells {
8417
8470
  rowHeight,
8418
8471
  cellValue,
8419
8472
  transformValue,
8420
- style
8473
+ style,
8474
+ references
8421
8475
  }
8422
8476
  };
8423
8477
  return result;
@@ -9047,17 +9101,17 @@ class AITableGrid extends AITableGridBase {
9047
9101
  case AI_TABLE_ROW_ADD_BUTTON: {
9048
9102
  this.aiTableGridSelectionService.clearSelection();
9049
9103
  this.addRecord();
9050
- return;
9104
+ break;
9051
9105
  }
9052
9106
  case AI_TABLE_ROW_SELECT_CHECKBOX: {
9053
9107
  const pointRecordId = context.linearRows()[pointRowIndex]?._id;
9054
9108
  this.selectRecord(pointRecordId);
9055
- return;
9109
+ break;
9056
9110
  }
9057
9111
  case AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX: {
9058
9112
  const isChecked = this.aiTable.selection().selectAllState === AITableSelectAllState.all;
9059
9113
  this.toggleSelectAll(!isChecked);
9060
- return;
9114
+ break;
9061
9115
  }
9062
9116
  case AI_TABLE_FIELD_ADD_BUTTON: {
9063
9117
  this.aiTableGridSelectionService.clearSelection();
@@ -9067,7 +9121,7 @@ class AITableGrid extends AITableGridBase {
9067
9121
  x: fieldGroupRect.x + containerRect.x,
9068
9122
  y: containerRect.y + fieldGroupRect.y + fieldGroupRect.height
9069
9123
  });
9070
- return;
9124
+ break;
9071
9125
  }
9072
9126
  case AI_TABLE_FIELD_HEAD_MORE:
9073
9127
  mouseEvent.preventDefault();
@@ -9095,36 +9149,52 @@ class AITableGrid extends AITableGridBase {
9095
9149
  editFieldPosition
9096
9150
  });
9097
9151
  }
9098
- return;
9152
+ break;
9099
9153
  }
9154
+ const targetNameDetail = getDetailByTargetName(e.event.target.name());
9155
+ this.aiClick.emit({
9156
+ ...e,
9157
+ targetNameDetail
9158
+ });
9159
+ return;
9100
9160
  }
9101
9161
  stageDblclick(e) {
9162
+ const _targetName = e.event.target.name();
9163
+ const targetNameDetail = getDetailByTargetName(_targetName);
9102
9164
  if (this.aiReadonly()) {
9165
+ this.aiDbClick.emit({
9166
+ ...e,
9167
+ targetNameDetail
9168
+ });
9103
9169
  return;
9104
9170
  }
9105
- const _targetName = e.event.target.name();
9106
- const { fieldId, recordId } = getDetailByTargetName(_targetName);
9171
+ const { fieldId, recordId } = targetNameDetail;
9107
9172
  if (!recordId || !fieldId) {
9108
9173
  return;
9109
9174
  }
9110
9175
  const field = this.aiTable.fieldsMap()[fieldId];
9111
9176
  const fieldType = field.type;
9112
- if (!DBL_CLICK_EDIT_TYPE.includes(fieldType)) {
9113
- return;
9177
+ if (DBL_CLICK_EDIT_TYPE.includes(fieldType)) {
9178
+ setTimeout(() => {
9179
+ this.aiTableGridEventService.openCellEditor(this.aiTable, {
9180
+ viewContainerRef: this.viewContainerRef,
9181
+ container: this.containerElement(),
9182
+ coordinate: this.coordinate(),
9183
+ fieldId: fieldId,
9184
+ recordId: recordId,
9185
+ references: this.aiReferences(),
9186
+ updateFieldValue: (value) => {
9187
+ this.aiUpdateFieldValue.emit(value);
9188
+ }
9189
+ });
9190
+ }, 0);
9114
9191
  }
9115
- setTimeout(() => {
9116
- this.aiTableGridEventService.openCellEditor(this.aiTable, {
9117
- viewContainerRef: this.viewContainerRef,
9118
- container: this.containerElement(),
9119
- coordinate: this.coordinate(),
9120
- fieldId: fieldId,
9121
- recordId: recordId,
9122
- references: this.aiReferences(),
9123
- updateFieldValue: (value) => {
9124
- this.aiUpdateFieldValue.emit(value);
9125
- }
9192
+ else {
9193
+ this.aiDbClick.emit({
9194
+ ...e,
9195
+ targetNameDetail
9126
9196
  });
9127
- }, 0);
9197
+ }
9128
9198
  }
9129
9199
  bindWheel() {
9130
9200
  fromEvent(this.containerElement(), 'wheel', { passive: false })
@@ -9323,5 +9393,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
9323
9393
  * Generated bundle index. Do not edit.
9324
9394
  */
9325
9395
 
9326
- export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsSameOptionPipe, AITableFieldSetting, AITableFieldType, AITableFilterOperation, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridSelectionService, AITableMemberType, AITableMouseDownType, AITableQueries, AITableRenderer, AITableRowColumnType, AITableRowType, AITableSelectAllState, 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_FIELD_ITEM_HEIGHT, 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_FIELD_ITEM_MARGIN_RIGHT, AI_TABLE_FIELD_MAX_WIDTH, AI_TABLE_FIELD_MIDDLE_WIDTH, AI_TABLE_FIELD_MINI_WIDTH, AI_TABLE_FIELD_MIN_WIDTH, AI_TABLE_FILE_ICON_ITEM_HEIGHT, AI_TABLE_FILE_ICON_SIZE, 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, AttachmentPath, 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, DragType, FONT_SIZE_SM, FieldModelMap, 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, WebOutlinedPath, aiTableFragmentAttribute, buildClipboardData, buildGridData, buildGridLinearRows, castToString, compareNumber, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, extractLinkHref, extractText, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getDefaultFieldValue, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getFieldValue, getHoverCell, getHoverEditorBoxOffset, getHoverEditorSpace, getMousePosition, getPlaceHolderCellsConfigs, getSystemFieldValue, getTargetName, getTextWidth, getVisibleRangeInfo, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isArrayField, isCellMatchKeywords, isClipboardReadSupported, isClipboardReadTextSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isEmpty, isMac, isNumberFiled, isSameFieldOption, isSelectedField, isSystemField, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, readFromClipboard, scrollMax, setMouseStyle, shortIdCreator, shortIdsCreator, stringInclude, textDataCache, transformCellValue, writeToAITable, writeToClipboard, zhIntlCollator };
9396
+ export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsSameOptionPipe, AITableFieldSetting, AITableFieldType, AITableFilterOperation, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridSelectionService, AITableMemberType, AITableMouseDownType, AITableQueries, AITableRenderer, AITableRowColumnType, AITableRowType, AITableSelectAllState, AITableSelectOptionStyle, AITableStatType, AI_TABLE_ACTION_COMMON_RADIUS, AI_TABLE_ACTION_COMMON_RIGHT_PADDING, 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_ATTACHMENT_ADD, AI_TABLE_CELL_ATTACHMENT_FILE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, AI_TABLE_CELL_FIELD_ITEM_HEIGHT, 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_FIELD_ITEM_MARGIN_RIGHT, AI_TABLE_FIELD_MAX_WIDTH, AI_TABLE_FIELD_MIDDLE_WIDTH, AI_TABLE_FIELD_MINI_WIDTH, AI_TABLE_FIELD_MIN_WIDTH, AI_TABLE_FILE_ICON_ITEM_HEIGHT, AI_TABLE_FILE_ICON_SIZE, 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, AttachmentPath, 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, DragType, FONT_SIZE_SM, FieldModelMap, 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, WebOutlinedPath, aiTableFragmentAttribute, buildClipboardData, buildGridData, buildGridLinearRows, castToString, compareNumber, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, extractLinkHref, extractText, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getDefaultFieldValue, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getFieldValue, getHoverCell, getHoverEditorBoxOffset, getHoverEditorSpace, getMousePosition, getPlaceHolderCellsConfigs, getSystemFieldValue, getTargetName, getTextWidth, getVisibleRangeInfo, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isArrayField, isCellMatchKeywords, isClipboardReadSupported, isClipboardReadTextSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isEmpty, isMac, isNumberFiled, isSameFieldOption, isSelectedField, isSystemField, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, readFromClipboard, scrollMax, setMouseStyle, shortIdCreator, shortIdsCreator, stringInclude, textDataCache, transformCellValue, writeToAITable, writeToClipboard, zhIntlCollator };
9327
9397
  //# sourceMappingURL=ai-table-grid.mjs.map