@ai-table/grid 0.0.42 → 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 (58) 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/cell-editors/link/link-editor.component.mjs +2 -2
  10. package/esm2022/components/field-menu/field-menu.component.mjs +9 -3
  11. package/esm2022/constants/grid.mjs +1 -2
  12. package/esm2022/constants/table.mjs +6 -2
  13. package/esm2022/grid-base.component.mjs +4 -2
  14. package/esm2022/grid.component.mjs +39 -23
  15. package/esm2022/renderer/components/action-icon.component.mjs +117 -0
  16. package/esm2022/renderer/components/cells/attachment.component.mjs +117 -0
  17. package/esm2022/renderer/components/cells/index.mjs +3 -1
  18. package/esm2022/renderer/components/hover-cell.component.mjs +7 -7
  19. package/esm2022/renderer/drawers/cell-drawer.mjs +4 -7
  20. package/esm2022/types/cell.mjs +1 -1
  21. package/esm2022/types/component-config.mjs +1 -1
  22. package/esm2022/types/field.mjs +1 -1
  23. package/esm2022/utils/clipboard/paste.mjs +27 -14
  24. package/esm2022/utils/common.mjs +6 -5
  25. package/esm2022/utils/field/model/date.mjs +41 -18
  26. package/esm2022/utils/field/model/progress.mjs +11 -4
  27. package/esm2022/utils/file.mjs +1 -93
  28. package/esm2022/utils/hover-cell.mjs +1 -8
  29. package/fesm2022/ai-table-grid.mjs +1383 -1272
  30. package/fesm2022/ai-table-grid.mjs.map +1 -1
  31. package/grid-base.component.d.ts +4 -1
  32. package/grid-base.component.d.ts.map +1 -1
  33. package/grid.component.d.ts.map +1 -1
  34. package/package.json +1 -1
  35. package/renderer/components/action-icon.component.d.ts +47 -0
  36. package/renderer/components/action-icon.component.d.ts.map +1 -0
  37. package/renderer/components/cells/attachment.component.d.ts +16 -0
  38. package/renderer/components/cells/attachment.component.d.ts.map +1 -0
  39. package/renderer/components/cells/index.d.ts +1 -0
  40. package/renderer/components/cells/index.d.ts.map +1 -1
  41. package/renderer/drawers/cell-drawer.d.ts.map +1 -1
  42. package/types/cell.d.ts +1 -0
  43. package/types/cell.d.ts.map +1 -1
  44. package/types/component-config.d.ts +13 -1
  45. package/types/component-config.d.ts.map +1 -1
  46. package/types/field.d.ts +1 -1
  47. package/types/field.d.ts.map +1 -1
  48. package/utils/clipboard/paste.d.ts.map +1 -1
  49. package/utils/common.d.ts +1 -1
  50. package/utils/common.d.ts.map +1 -1
  51. package/utils/field/model/date.d.ts.map +1 -1
  52. package/utils/field/model/progress.d.ts.map +1 -1
  53. package/utils/file.d.ts +0 -9
  54. package/utils/file.d.ts.map +1 -1
  55. package/utils/hover-cell.d.ts.map +1 -1
  56. package/esm2022/utils/icon.mjs +0 -48
  57. package/utils/icon.d.ts +0 -19
  58. package/utils/icon.d.ts.map +0 -1
@@ -1089,7 +1089,7 @@ class LinkCellEditorComponent extends AbstractEditCellEditor {
1089
1089
  }
1090
1090
  updateValue() {
1091
1091
  if (!this.isValidLink({ text: this.text, url: this.url ?? '' })) {
1092
- this.notifyService.error(undefined, '链接格式不正确');
1092
+ this.notifyService.error('链接格式不正确');
1093
1093
  return;
1094
1094
  }
1095
1095
  this.modelValue = this.createLinkValue({ text: this.text, url: this.url ?? '' });
@@ -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
  }
@@ -2711,14 +2715,43 @@ function cellValueToSortValue$4(cellValue) {
2711
2715
  }
2712
2716
  function transformDateValue(text) {
2713
2717
  const value = text.trim();
2714
- const pattern = /^\d{4}-\d{1,2}-\d{1,2}$/;
2715
- if (value && !isEmpty(value) && pattern.test(value)) {
2716
- const dateValue = {
2717
- timestamp: new TinyDate(value).getUnixTime()
2718
+ if (!value || isEmpty(value))
2719
+ return null;
2720
+ // 基础日期格式:支持识别 - / . 年月日 作为分隔符
2721
+ const datePattern = String.raw `(?:(\d{2}|\d{4})[-/.年](\d{1,2})[-/.月](\d{1,2})日?)`;
2722
+ const timePattern = String.raw `(?:\s+(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?)?`;
2723
+ const pattern = new RegExp(`^${datePattern}${timePattern}$`);
2724
+ const match = value.match(pattern);
2725
+ if (!match)
2726
+ return null;
2727
+ try {
2728
+ let [_, year, month, day] = match;
2729
+ if (year.length === 2) {
2730
+ const currentYear = new Date().getFullYear();
2731
+ const century = Math.floor(currentYear / 100) * 100;
2732
+ const twoDigitYear = parseInt(year);
2733
+ year = String(twoDigitYear > currentYear % 100 ? century - 100 + twoDigitYear : century + twoDigitYear);
2734
+ }
2735
+ const monthNum = parseInt(month);
2736
+ const dayNum = parseInt(day);
2737
+ if (monthNum < 1 || monthNum > 12) {
2738
+ console.warn('Invalid month:', monthNum);
2739
+ return null;
2740
+ }
2741
+ const maxDays = new Date(parseInt(year), monthNum, 0).getDate();
2742
+ if (dayNum < 1 || dayNum > maxDays) {
2743
+ console.warn('Invalid day:', dayNum);
2744
+ return null;
2745
+ }
2746
+ const standardDate = `${year}-${String(monthNum).padStart(2, '0')}-${String(dayNum).padStart(2, '0')}`;
2747
+ return {
2748
+ timestamp: new TinyDate(standardDate).getUnixTime()
2718
2749
  };
2719
- return dateValue;
2720
2750
  }
2721
- return null;
2751
+ catch (error) {
2752
+ console.warn('Invalid date:', value);
2753
+ return null;
2754
+ }
2722
2755
  }
2723
2756
 
2724
2757
  class LinkField extends Field {
@@ -2976,10 +3009,17 @@ function toProgressFieldValue(plainText, targetField, originData) {
2976
3009
  break;
2977
3010
  }
2978
3011
  }
3012
+ const progressRegex = /^(?:100|[1-9]?\d(?:\.\d+)?)\s*%$/;
3013
+ if (progressRegex.test(value)) {
3014
+ value = parseFloat(value);
3015
+ }
2979
3016
  if (!isEmpty(value)) {
2980
- const progressValue = Number(value);
2981
- if (!Number.isNaN(progressValue) && progressValue >= 0 && progressValue <= 100) {
2982
- 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
+ }
2983
3023
  }
2984
3024
  }
2985
3025
  return null;
@@ -3299,27 +3339,39 @@ function extractContentFromClipboardText(clipboardText) {
3299
3339
  .filter((row) => row.length > 0 && row.some((cell) => cell.trim().length > 0));
3300
3340
  return contents;
3301
3341
  }
3342
+ function processTableCell(cellHtml) {
3343
+ const linkPattern = /<a[^>]*?href=["']([^"']+)["'][^>]*?>([^<]*?)<\/a>/i;
3344
+ const match = cellHtml.match(linkPattern);
3345
+ const link = match ? { href: match[1], text: match[2] } : null;
3346
+ const content = link ? cellHtml.replace(linkPattern, `[LINK:${link.text}](${link.href})`) : cellHtml;
3347
+ const cleanContent = content
3348
+ .replace(/<[^>]+>/g, '')
3349
+ .replace(/&nbsp;/g, ' ')
3350
+ .replace(/\s+/g, ' ')
3351
+ .trim();
3352
+ return link ? cleanContent.replace(`[LINK:${link.text}](${link.href})`, `<a href="${link.href}">${link.text}</a>`) : cleanContent;
3353
+ }
3302
3354
  function extractContentFromClipboardHtml(clipboardHtml) {
3303
3355
  const tablePattern = /<table[^>]*>([\s\S]*?)<\/table>/i;
3304
3356
  const trPattern = /<tr[^>]*>([\s\S]*?)<\/tr>/gi;
3305
- const cellPattern = /<td[^>]*>([\s\S]*?)<\/td>/gi;
3306
- const contents = [];
3357
+ const tdPattern = /<td[^>]*?>([\s\S]*?)<\/td>/gi;
3307
3358
  try {
3308
3359
  const tableMatch = clipboardHtml.match(tablePattern);
3309
3360
  const tableContent = tableMatch ? tableMatch[1] : clipboardHtml;
3310
3361
  const rows = tableContent.match(trPattern) || [];
3311
- rows.forEach((row) => {
3312
- const rowContent = [];
3313
- const cells = row.match(cellPattern) || [];
3314
- cells.forEach((cell) => {
3315
- const content = cell.replace(/<td>|<\/td>/g, '').trim();
3316
- rowContent.push(content);
3317
- });
3318
- contents.push(rowContent);
3319
- });
3320
- return contents;
3362
+ return rows
3363
+ .map((row) => {
3364
+ const contents = [];
3365
+ let tdMatch;
3366
+ while ((tdMatch = tdPattern.exec(row)) !== null) {
3367
+ contents.push(processTableCell(tdMatch[1]));
3368
+ }
3369
+ return contents;
3370
+ })
3371
+ .filter((row) => row.length > 0);
3321
3372
  }
3322
3373
  catch (error) {
3374
+ console.warn('Failed to extract content from HTML:', error);
3323
3375
  return [];
3324
3376
  }
3325
3377
  }
@@ -3401,7 +3453,8 @@ function appendRecord(aiTable, actions) {
3401
3453
  });
3402
3454
  }
3403
3455
  function appendField(aiTable, originField, actions) {
3404
- 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 : '';
3405
3458
  let defaultFieldValue;
3406
3459
  if (originField) {
3407
3460
  defaultFieldValue = {
@@ -5063,927 +5116,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
5063
5116
  }]
5064
5117
  }] });
5065
5118
 
5066
- var cellComponents = /*#__PURE__*/Object.freeze({
5067
- __proto__: null,
5068
- AITableCellLink: AITableCellLink
5069
- });
5070
-
5071
- const componentMap = {};
5072
- Object.values(cellComponents).forEach((cellComponent) => {
5073
- componentMap[cellComponent.fieldType] = cellComponent;
5074
- });
5075
-
5076
- function getHoverCell(aiTable) {
5077
- const pointPosition = aiTable.context.pointPosition();
5078
- const { fieldId, recordId } = getDetailByTargetName(pointPosition.realTargetName) ?? {};
5079
- if (!recordId || !fieldId) {
5080
- return;
5081
- }
5082
- const record = aiTable.recordsMap()[recordId];
5083
- const field = aiTable.fieldsMap()[fieldId];
5084
- if (!record || !field || !recordId || !fieldId) {
5085
- return;
5086
- }
5087
- const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, fieldId]);
5088
- const transformValue = transformCellValue(aiTable, field, cellValue) || {};
5089
- if (Object.keys(transformValue).length === 0) {
5090
- return;
5091
- }
5092
- const renderComponentDefinition = componentMap[field?.type];
5093
- if (!renderComponentDefinition) {
5094
- return;
5095
- }
5096
- return {
5097
- field,
5098
- recordId,
5099
- fieldId,
5100
- renderComponentDefinition
5101
- };
5102
- }
5103
-
5104
- class AITableGridEventService {
5105
- constructor() {
5106
- this.dblClickEvent$ = new Subject();
5107
- this.mousedownEvent$ = new Subject();
5108
- this.mouseoverEvent$ = new Subject();
5109
- this.globalMouseoverEvent$ = new Subject();
5110
- this.globalMousedownEvent$ = new Subject();
5111
- this.destroyRef = inject(DestroyRef);
5112
- this.thyPopover = inject(ThyPopover);
5113
- }
5114
- initialize(aiTable, aiFieldRenderers) {
5115
- this.aiTable = aiTable;
5116
- this.aiFieldRenderers = aiFieldRenderers;
5117
- }
5118
- registerEvents(element) {
5119
- fromEvent(element, 'dblclick', { passive: true })
5120
- .pipe(takeUntilDestroyed(this.destroyRef))
5121
- .subscribe((event) => {
5122
- this.dblClickEvent$.next(event);
5123
- });
5124
- fromEvent(element, 'mouseover', { passive: true })
5125
- .pipe(debounceTime(80), takeUntilDestroyed(this.destroyRef))
5126
- .subscribe((event) => {
5127
- this.mouseoverEvent$.next(event);
5128
- });
5129
- fromEvent(document, 'mouseover', { passive: true })
5130
- .pipe(takeUntilDestroyed(this.destroyRef))
5131
- .subscribe((event) => {
5132
- this.globalMouseoverEvent$.next(event);
5133
- });
5134
- fromEvent(element, 'mousedown', { passive: true })
5135
- .pipe(takeUntilDestroyed(this.destroyRef))
5136
- .subscribe((event) => {
5137
- this.mousedownEvent$.next(event);
5138
- });
5139
- fromEvent(document, 'mousedown', { passive: true })
5140
- .pipe(takeUntilDestroyed(this.destroyRef))
5141
- .subscribe((event) => {
5142
- this.globalMousedownEvent$.next(event);
5143
- });
5144
- }
5145
- getEditorComponent(type) {
5146
- const filedRenderSchema = this.aiFieldRenderers && this.aiFieldRenderers[type];
5147
- if (filedRenderSchema && filedRenderSchema.editor) {
5148
- return {
5149
- component: filedRenderSchema.editor,
5150
- isInternalComponent: false
5151
- };
5152
- }
5153
- return {
5154
- component: GRID_CELL_EDITOR_MAP[type],
5155
- isInternalComponent: true
5156
- };
5157
- }
5158
- openEdit(cellDom) {
5159
- const { x, y, width, height } = cellDom.getBoundingClientRect();
5160
- const fieldId = cellDom.getAttribute('fieldId');
5161
- const recordId = cellDom.getAttribute('recordId');
5162
- const { component } = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
5163
- const ref = this.thyPopover.open(component, {
5164
- origin: cellDom,
5165
- originPosition: {
5166
- x: x - 1,
5167
- y: y + 1,
5168
- width: width + 2,
5169
- height: height + 2
5170
- },
5171
- width: width + 1 + 'px',
5172
- height: height + 2 + 'px',
5173
- placement: 'top',
5174
- offset: -(height + 4),
5175
- minWidth: width,
5176
- initialState: {
5177
- fieldId: fieldId,
5178
- recordId: recordId,
5179
- aiTable: this.aiTable
5180
- },
5181
- panelClass: 'grid-cell-editor',
5182
- outsideClosable: false,
5183
- hasBackdrop: false,
5184
- manualClosure: true,
5185
- animationDisabled: true,
5186
- autoAdaptive: true
5187
- });
5188
- return ref;
5189
- }
5190
- getOriginPosition(aiTable, options) {
5191
- const { container, coordinate, recordId, fieldId, isHoverEdit } = options;
5192
- const { scrollState } = aiTable.context;
5193
- const { rowHeight, columnCount } = coordinate;
5194
- const cell = [recordId, fieldId];
5195
- const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, cell);
5196
- const originX = coordinate.getColumnOffset(columnIndex);
5197
- const originY = coordinate.getRowOffset(rowIndex);
5198
- const columnWidth = coordinate.getColumnWidth(columnIndex);
5199
- const { width: originWidth, offset: originOffset } = getCellHorizontalPosition({
5200
- columnWidth,
5201
- columnIndex,
5202
- columnCount
5203
- });
5204
- const originRect = container.getBoundingClientRect();
5205
- const isFrozenColumn = AITable.isFrozenColumn(aiTable, columnIndex);
5206
- const scrollLeft = isFrozenColumn ? 0 : scrollState().scrollLeft;
5207
- const scrollTop = scrollState().scrollTop;
5208
- const originPosition = {
5209
- x: originX + originOffset - scrollLeft + originRect.x,
5210
- y: originY - scrollTop + originRect.y,
5211
- width: originWidth,
5212
- height: rowHeight
5213
- };
5214
- let x = originPosition.x + getEditorBoxOffset();
5215
- let y = originPosition.y + getEditorBoxOffset();
5216
- let width = getEditorSpace(originPosition.width);
5217
- let height = getEditorSpace(originPosition.height);
5218
- // hover 编辑组件无边框
5219
- if (isHoverEdit) {
5220
- x = originPosition.x + getHoverEditorBoxOffset();
5221
- y = originPosition.y + getHoverEditorBoxOffset();
5222
- width = getHoverEditorSpace(originPosition.width);
5223
- height = getHoverEditorSpace(originPosition.height);
5224
- }
5225
- return {
5226
- ...originPosition,
5227
- x: x,
5228
- y: y,
5229
- width: width,
5230
- height: height
5231
- };
5232
- }
5233
- openCellEditor(aiTable, options) {
5234
- const { container, recordId, fieldId, isHoverEdit, references } = options;
5235
- const { component, isInternalComponent } = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
5236
- const offsetOriginPosition = this.getOriginPosition(aiTable, options);
5237
- this.cellEditorPopoverRef = this.thyPopover.open(component, {
5238
- viewContainerRef: isInternalComponent ? undefined : options?.viewContainerRef,
5239
- origin: container,
5240
- originPosition: offsetOriginPosition,
5241
- width: offsetOriginPosition.width + 'px',
5242
- height: offsetOriginPosition.height + 'px',
5243
- minWidth: offsetOriginPosition.width + 'px',
5244
- placement: 'bottom',
5245
- offset: -offsetOriginPosition.height,
5246
- initialState: {
5247
- fieldId: fieldId,
5248
- recordId: recordId,
5249
- references,
5250
- aiTable: aiTable
5251
- },
5252
- panelClass: 'grid-cell-editor',
5253
- outsideClosable: false,
5254
- hasBackdrop: false,
5255
- manualClosure: true,
5256
- animationDisabled: true,
5257
- autoAdaptive: true
5258
- });
5259
- if (this.cellEditorPopoverRef) {
5260
- const wheelEvent = fromEvent(this.cellEditorPopoverRef.componentInstance.elementRef.nativeElement, 'wheel').subscribe((event) => {
5261
- const field = aiTable.fieldsMap()[fieldId];
5262
- if (field.type === AITableFieldType.text || field.type === AITableFieldType.richText) {
5263
- return;
5264
- }
5265
- event.preventDefault();
5266
- this.aiTable.context?.scrollAction({
5267
- deltaX: event.deltaX,
5268
- deltaY: event.deltaY,
5269
- shiftKey: event.shiftKey,
5270
- callback: () => {
5271
- const originPosition = this.getOriginPosition(aiTable, options);
5272
- const positionStrategy = this.cellEditorPopoverRef
5273
- .getOverlayRef()
5274
- .getConfig().positionStrategy;
5275
- positionStrategy.setOrigin(originPosition);
5276
- positionStrategy.apply();
5277
- }
5278
- });
5279
- });
5280
- this.cellEditorPopoverRef.afterClosed().subscribe(() => {
5281
- wheelEvent.unsubscribe();
5282
- this.cellEditorPopoverRef = null;
5283
- });
5284
- this.cellEditorPopoverRef.componentInstance.updateFieldValue.subscribe((value) => {
5285
- options.updateFieldValue(value);
5286
- });
5287
- }
5288
- return this.cellEditorPopoverRef;
5289
- }
5290
- closeCellEditor() {
5291
- if (this.cellEditorPopoverRef) {
5292
- this.cellEditorPopoverRef.close();
5293
- this.cellEditorPopoverRef = null;
5294
- }
5295
- }
5296
- getCurrentEditCell() {
5297
- if (this.cellEditorPopoverRef) {
5298
- const recordId = this.cellEditorPopoverRef.componentInstance?.recordId;
5299
- const fieldId = this.cellEditorPopoverRef.componentInstance?.fieldId;
5300
- if (recordId && fieldId) {
5301
- return {
5302
- recordId,
5303
- fieldId
5304
- };
5305
- }
5306
- return null;
5307
- }
5308
- return null;
5309
- }
5310
- openContextMenu(aiTable, options) {
5311
- const { origin, position, menuItems, targetName, viewContainerRef } = options;
5312
- const ref = this.thyPopover.open(AITableContextMenu, {
5313
- origin: origin,
5314
- originPosition: position,
5315
- placement: 'bottomLeft',
5316
- insideClosable: true,
5317
- viewContainerRef,
5318
- initialState: {
5319
- aiTable,
5320
- menuItems,
5321
- targetName,
5322
- position
5323
- }
5324
- });
5325
- return ref;
5326
- }
5327
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5328
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService }); }
5329
- }
5330
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, decorators: [{
5331
- type: Injectable
5332
- }] });
5333
-
5334
- class AITableGridBase {
5335
- constructor() {
5336
- this.aiRecords = model.required();
5337
- this.aiFields = model.required();
5338
- this.aiContextMenuItems = input([]);
5339
- this.aiFieldConfig = input();
5340
- this.aiReadonly = input();
5341
- this.aiPlugins = input();
5342
- this.aiReferences = input.required();
5343
- this.aiBuildRenderDataFn = input();
5344
- this.aiKeywords = input();
5345
- this.AITableFieldType = AITableFieldType;
5346
- this.AITableSelectOptionStyle = AITableSelectOptionStyle;
5347
- this.isSelectedAll = computed(() => {
5348
- return this.aiTable.selection().selectedRecords.size === this.aiRecords().length;
5349
- });
5350
- this.aiTableInitialized = output();
5351
- this.aiAddRecord = output();
5352
- this.aiAddField = output();
5353
- this.aiMoveField = output();
5354
- this.aiUpdateFieldValue = output();
5355
- this.aiSetField = output();
5356
- this.fieldMenus = computed(() => {
5357
- return this.aiFieldConfig()?.fieldMenus || [];
5358
- });
5359
- this.gridData = computed(() => {
5360
- if (this.aiBuildRenderDataFn && this.aiBuildRenderDataFn() && this.aiTable) {
5361
- return this.aiBuildRenderDataFn()(this.aiTable);
5362
- }
5363
- return {
5364
- records: this.aiRecords(),
5365
- fields: this.aiFields()
5366
- };
5367
- });
5368
- this.ngZone = inject(NgZone);
5369
- this.elementRef = inject(ElementRef);
5370
- this.destroyRef = inject(DestroyRef);
5371
- this.aiTableGridFieldService = inject(AITableGridFieldService);
5372
- this.aiTableGridEventService = inject(AITableGridEventService);
5373
- this.aiTableGridSelectionService = inject(AITableGridSelectionService);
5374
- }
5375
- ngOnInit() {
5376
- this.initAITable();
5377
- this.initService();
5378
- }
5379
- initAITable() {
5380
- this.aiTable = createAITable(this.aiRecords, this.aiFields, this.gridData);
5381
- this.aiPlugins()?.forEach((plugin) => {
5382
- this.aiTable = plugin(this.aiTable);
5383
- });
5384
- this.aiTableInitialized.emit(this.aiTable);
5385
- }
5386
- initService() {
5387
- this.aiTableGridEventService.initialize(this.aiTable, this.aiFieldConfig()?.fieldRenderers);
5388
- this.aiTableGridSelectionService.initialize(this.aiTable);
5389
- this.aiTableGridEventService.registerEvents(this.elementRef.nativeElement);
5390
- this.aiTableGridFieldService.initAIFieldConfig(this.aiFieldConfig());
5391
- AI_TABLE_GRID_FIELD_SERVICE_MAP.set(this.aiTable, this.aiTableGridFieldService);
5392
- }
5393
- addRecord() {
5394
- const records = this.aiRecords();
5395
- const recordCount = records.length;
5396
- this.aiAddRecord.emit({
5397
- originId: recordCount > 0 ? records[records.length - 1]._id : ''
5398
- });
5399
- }
5400
- selectRecord(recordId) {
5401
- this.aiTableGridSelectionService.selectRecord(recordId);
5402
- }
5403
- toggleSelectAll(checked) {
5404
- this.aiTableGridSelectionService.toggleSelectAll(checked);
5405
- }
5406
- addField(gridColumnBlank, position) {
5407
- const field = createDefaultField(this.aiTable, AITableFieldType.text);
5408
- const popoverRef = this.aiTableGridFieldService.editFieldProperty(this.aiTable, {
5409
- field,
5410
- isUpdate: false,
5411
- origin: gridColumnBlank,
5412
- position
5413
- });
5414
- if (popoverRef && !this.aiFieldConfig()?.fieldSettingComponent) {
5415
- popoverRef.componentInstance.addField.subscribe((defaultValue) => {
5416
- const fields = this.gridData().fields;
5417
- const fieldCount = fields.length;
5418
- this.aiAddField.emit({
5419
- originId: fieldCount > 0 ? fields[fields.length - 1]._id : '',
5420
- defaultValue
5421
- });
5422
- });
5423
- }
5424
- }
5425
- subscribeEvents() {
5426
- this.ngZone.runOutsideAngular(() => {
5427
- this.aiTableGridEventService.dblClickEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
5428
- this.dblClick(event);
5429
- });
5430
- this.aiTableGridEventService.mousedownEvent$
5431
- .pipe(mergeWith(this.aiTableGridEventService.globalMousedownEvent$), takeUntilDestroyed(this.destroyRef))
5432
- .subscribe((event) => {
5433
- this.aiTableGridSelectionService.updateSelect(event);
5434
- });
5435
- this.aiTableGridEventService.mouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
5436
- this.mouseoverHandle(event);
5437
- });
5438
- this.aiTableGridEventService.globalMouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
5439
- this.closeHoverCellEditor(event);
5440
- });
5441
- });
5442
- }
5443
- dblClick(event) {
5444
- const cellDom = event.target.closest('.grid-cell');
5445
- const type = cellDom && cellDom.getAttribute('type');
5446
- if (type && DBL_CLICK_EDIT_TYPE.includes(type)) {
5447
- this.aiTableGridEventService.openEdit(cellDom);
5448
- }
5449
- }
5450
- mouseoverHandle(event) {
5451
- if (this.mouseoverRef) {
5452
- this.mouseoverRef?.close();
5453
- }
5454
- const cellDom = event.target.closest('.grid-cell');
5455
- const type = cellDom && cellDom.getAttribute('type');
5456
- if (type && MOUSEOVER_EDIT_TYPE.includes(type)) {
5457
- this.mouseoverRef = this.aiTableGridEventService.openEdit(cellDom);
5458
- }
5459
- }
5460
- closeHoverCellEditor(e) {
5461
- if (this.mouseoverRef) {
5462
- const hasGrid = e.target && e.target.closest('.ai-table-grid');
5463
- const hasCellEditor = e.target && e.target.closest('.grid-cell-editor');
5464
- if (!hasGrid && !hasCellEditor) {
5465
- this.mouseoverRef.close();
5466
- }
5467
- }
5468
- }
5469
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5470
- 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 }); }
5471
- }
5472
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, decorators: [{
5473
- type: Component,
5474
- args: [{
5475
- selector: 'ai-table-grid-base',
5476
- template: '',
5477
- standalone: true,
5478
- changeDetection: ChangeDetectionStrategy.OnPush
5479
- }]
5480
- }] });
5481
-
5482
- class AITableDomGrid extends AITableGridBase {
5483
- ngOnInit() {
5484
- super.ngOnInit();
5485
- this.subscribeEvents();
5486
- }
5487
- openFieldMenu(e, field, fieldAction) {
5488
- const moreBtn = e.target.closest('.grid-field-action');
5489
- this.aiTableGridFieldService.openFieldMenu(this.aiTable, {
5490
- origin: moreBtn,
5491
- editOrigin: fieldAction,
5492
- fieldId: field._id,
5493
- fieldMenus: this.fieldMenus()
5494
- });
5495
- }
5496
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
5497
- 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 }); }
5498
- }
5499
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, decorators: [{
5500
- type: Component,
5501
- args: [{ selector: 'ai-table-dom-grid', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
5502
- class: 'ai-table-grid ai-table-dom-grid'
5503
- }, imports: [
5504
- NgClass,
5505
- NgComponentOutlet,
5506
- CommonModule,
5507
- FormsModule,
5508
- SelectOptionPipe,
5509
- SelectOptionsPipe,
5510
- ThyTag,
5511
- ThyPopoverModule,
5512
- ThyIcon,
5513
- ThyRate,
5514
- ThyProgress,
5515
- AITableFieldSetting,
5516
- ThyDatePickerFormatPipe,
5517
- ThyFlexibleText,
5518
- ThyStopPropagationDirective,
5519
- AITableFieldMenu,
5520
- ThyAction,
5521
- ThyDropdownDirective,
5522
- ThyDropdownMenuComponent,
5523
- ThyCheckboxModule,
5524
- ProgressEditorComponent,
5525
- ThyAvatarModule,
5526
- NgTemplateOutlet,
5527
- IsSelectRecordPipe,
5528
- ProgressEditorComponent,
5529
- SelectOptionComponent,
5530
- UserPipe,
5531
- SelectSettingPipe,
5532
- MemberSettingPipe
5533
- ], 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" }]
5534
- }] });
5535
-
5536
- class KoStage {
5537
- constructor() {
5538
- this.config = input();
5539
- this.koMouseover = new EventEmitter();
5540
- this.koMousemove = new EventEmitter();
5541
- this.koMouseout = new EventEmitter();
5542
- this.koMouseenter = new EventEmitter();
5543
- this.koMouseleave = new EventEmitter();
5544
- this.koMousedown = new EventEmitter();
5545
- this.koMouseup = new EventEmitter();
5546
- this.koWheel = new EventEmitter();
5547
- this.koContextmenu = new EventEmitter();
5548
- this.koClick = new EventEmitter();
5549
- this.koDblclick = new EventEmitter();
5550
- this.koTouchstart = new EventEmitter();
5551
- this.koTouchmove = new EventEmitter();
5552
- this.koTouchend = new EventEmitter();
5553
- this.koTap = new EventEmitter();
5554
- this.koDbltap = new EventEmitter();
5555
- this.koDragstart = new EventEmitter();
5556
- this.koDragmove = new EventEmitter();
5557
- this.koDragend = new EventEmitter();
5558
- this.cacheProps = {};
5559
- this.nodeContainer = inject(ElementRef).nativeElement;
5560
- effect(() => {
5561
- if (this.config()) {
5562
- if (!this._stage) {
5563
- this.initStage();
5564
- }
5565
- this.updateNode(this.config());
5566
- }
5567
- });
5568
- }
5569
- ngOnInit() {
5570
- this.initStage();
5571
- }
5572
- getNode() {
5573
- return this._stage;
5574
- }
5575
- initStage() {
5576
- this._stage = new Stage({
5577
- ...this.config(),
5578
- container: this.nodeContainer
5579
- });
5580
- }
5581
- updateNode(config) {
5582
- const props = {
5583
- ...config,
5584
- ...createListener(this)
5585
- };
5586
- applyNodeProps(this, props, this.cacheProps);
5587
- this.cacheProps = props;
5588
- }
5589
- ngOnDestroy() {
5590
- this._stage?.destroy();
5591
- }
5592
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5593
- 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: [
5594
- {
5595
- provide: KO_CONTAINER_TOKEN,
5596
- useExisting: KoStage
5597
- }
5598
- ], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5599
- }
5600
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, decorators: [{
5601
- type: Component,
5602
- args: [{
5603
- selector: 'ko-stage',
5604
- standalone: true,
5605
- template: `<ng-content></ng-content>`,
5606
- providers: [
5607
- {
5608
- provide: KO_CONTAINER_TOKEN,
5609
- useExisting: KoStage
5610
- }
5611
- ],
5612
- changeDetection: ChangeDetectionStrategy.OnPush
5613
- }]
5614
- }], ctorParameters: () => [], propDecorators: { koMouseover: [{
5615
- type: Output
5616
- }], koMousemove: [{
5617
- type: Output
5618
- }], koMouseout: [{
5619
- type: Output
5620
- }], koMouseenter: [{
5621
- type: Output
5622
- }], koMouseleave: [{
5623
- type: Output
5624
- }], koMousedown: [{
5625
- type: Output
5626
- }], koMouseup: [{
5627
- type: Output
5628
- }], koWheel: [{
5629
- type: Output
5630
- }], koContextmenu: [{
5631
- type: Output
5632
- }], koClick: [{
5633
- type: Output
5634
- }], koDblclick: [{
5635
- type: Output
5636
- }], koTouchstart: [{
5637
- type: Output
5638
- }], koTouchmove: [{
5639
- type: Output
5640
- }], koTouchend: [{
5641
- type: Output
5642
- }], koTap: [{
5643
- type: Output
5644
- }], koDbltap: [{
5645
- type: Output
5646
- }], koDragstart: [{
5647
- type: Output
5648
- }], koDragmove: [{
5649
- type: Output
5650
- }], koDragend: [{
5651
- type: Output
5652
- }] } });
5653
-
5654
- class KoComponent extends Component {
5655
- }
5656
-
5657
- const KoShapeTypes = {
5658
- Arc,
5659
- Arrow,
5660
- Circle,
5661
- Ellipse,
5662
- Image: Image$1,
5663
- Label,
5664
- Tag,
5665
- Line,
5666
- Path,
5667
- Rect,
5668
- RegularPolygon,
5669
- Ring,
5670
- Star,
5671
- Text,
5672
- TextPath,
5673
- Transformer,
5674
- Wedge,
5675
- Group,
5676
- Layer,
5677
- FastLayer
5678
- };
5679
-
5680
- class AITableIcon {
5681
- constructor() {
5682
- this.config = input.required();
5683
- this.groupConfig = computed(() => {
5684
- const { x, y, listening } = this.config();
5685
- return { x, y, listening };
5686
- });
5687
- this.squareShapeConfig = computed(() => {
5688
- const { name, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, strokeWidth = 1, background, cornerRadius, opacity } = this.config();
5689
- return {
5690
- name,
5691
- width: backgroundWidth || size,
5692
- height: backgroundHeight || size,
5693
- strokeWidth: strokeWidth,
5694
- fill: background || Colors.transparent,
5695
- cornerRadius,
5696
- opacity
5697
- };
5698
- });
5699
- this.iconConfig = computed(() => {
5700
- const { type, data, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, stroke, strokeWidth = 1, scaleX, scaleY, offsetX, offsetY, rotation, fill = Colors.gray600, transformsEnabled = 'position' } = this.config();
5701
- let pathData = data;
5702
- switch (type) {
5703
- case AITableCheckType.checked:
5704
- pathData = Check;
5705
- break;
5706
- case AITableCheckType.unchecked:
5707
- pathData = Unchecked;
5708
- break;
5709
- }
5710
- return {
5711
- x: backgroundWidth && (backgroundWidth - size * (scaleX || 1)) / 2,
5712
- y: backgroundHeight && (backgroundHeight - size * (scaleY || 1)) / 2,
5713
- data: pathData,
5714
- width: size,
5715
- height: size,
5716
- fill,
5717
- offsetX,
5718
- offsetY,
5719
- scaleX,
5720
- scaleY,
5721
- rotation,
5722
- stroke,
5723
- strokeWidth,
5724
- transformsEnabled,
5725
- perfectDrawEnabled: false,
5726
- listening: false
5727
- };
5728
- });
5729
- }
5730
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5731
- 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: `
5732
- <ko-group [config]="groupConfig()">
5733
- <ko-rect [config]="squareShapeConfig()"></ko-rect>
5734
- <ko-path [config]="iconConfig()"></ko-path>
5735
- </ko-group>
5736
- `, 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 }); }
5737
- }
5738
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, decorators: [{
5739
- type: Component,
5740
- args: [{
5741
- selector: 'ai-table-icon',
5742
- template: `
5743
- <ko-group [config]="groupConfig()">
5744
- <ko-rect [config]="squareShapeConfig()"></ko-rect>
5745
- <ko-path [config]="iconConfig()"></ko-path>
5746
- </ko-group>
5747
- `,
5748
- standalone: true,
5749
- imports: [KoContainer, KoShape],
5750
- changeDetection: ChangeDetectionStrategy.OnPush
5751
- }]
5752
- }] });
5753
-
5754
- class AITableAddField {
5755
- constructor() {
5756
- this.config = input.required();
5757
- this.btnWidth = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
5758
- this.x = computed(() => {
5759
- const lastColumnWidth = this.config().coordinate.getColumnWidth(this.config().columnStopIndex);
5760
- const lastColumnOffset = this.config().coordinate.getColumnOffset(this.config().columnStopIndex);
5761
- return lastColumnWidth + lastColumnOffset;
5762
- });
5763
- this.rectConfig = computed(() => {
5764
- const { pointPosition: { targetName }, readonly } = this.config();
5765
- const fill = targetName === AI_TABLE_FIELD_ADD_BUTTON ? Colors.gray80 : Colors.white;
5766
- return {
5767
- name: generateTargetName({
5768
- targetName: AI_TABLE_FIELD_ADD_BUTTON,
5769
- fieldId: this.config().fields[this.config().columnStopIndex]._id,
5770
- mouseStyle: readonly ? 'default' : 'pointer'
5771
- }),
5772
- x: AI_TABLE_OFFSET,
5773
- y: AI_TABLE_OFFSET,
5774
- width: this.config().coordinate.containerWidth - this.x() < this.btnWidth
5775
- ? this.btnWidth
5776
- : this.config().coordinate.containerWidth - this.x(),
5777
- height: this.config().coordinate.rowInitSize,
5778
- stroke: Colors.gray200,
5779
- strokeWidth: 1,
5780
- listening: true,
5781
- fill
5782
- };
5783
- });
5784
- this.addIconConfig = computed(() => {
5785
- const { readonly } = this.config();
5786
- const offsetY = (this.config().coordinate.rowInitSize - AI_TABLE_ICON_COMMON_SIZE) / 2;
5787
- return {
5788
- x: AI_TABLE_CELL_PADDING,
5789
- y: offsetY,
5790
- data: AddOutlinedPath,
5791
- fill: Colors.gray600,
5792
- listening: false,
5793
- visible: isNil(readonly) ? true : !readonly
5794
- };
5795
- });
5796
- }
5797
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5798
- 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: `
5799
- <ko-group [config]="{ x: x() }">
5800
- <ko-group>
5801
- <ko-rect [config]="rectConfig()"></ko-rect>
5802
- </ko-group>
5803
- <ko-group>
5804
- @if (addIconConfig().visible) {
5805
- <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
5806
- }
5807
- </ko-group>
5808
- </ko-group>
5809
- `, 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 }); }
5810
- }
5811
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, decorators: [{
5812
- type: Component,
5813
- args: [{
5814
- selector: 'ai-table-add-field',
5815
- template: `
5816
- <ko-group [config]="{ x: x() }">
5817
- <ko-group>
5818
- <ko-rect [config]="rectConfig()"></ko-rect>
5819
- </ko-group>
5820
- <ko-group>
5821
- @if (addIconConfig().visible) {
5822
- <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
5823
- }
5824
- </ko-group>
5825
- </ko-group>
5826
- `,
5827
- standalone: true,
5828
- imports: [KoContainer, KoShape, AITableIcon],
5829
- changeDetection: ChangeDetectionStrategy.OnPush
5830
- }]
5831
- }] });
5832
-
5833
- /**
5834
- * 用于处理表格行或单元格的布局和绘制。
5835
- * 它提供了基本的布局信息(如位置、大小等),并定义了常用的绘图方法(如渲染缩进区域、添加新字段的空白区域等)。
5836
- * 该类继承自 Drawer,并被其他更具体的布局类(如 RecordRowLayout)扩展和使用
5837
- */
5838
- class Layout extends Drawer {
5839
- constructor() {
5840
- super(...arguments);
5841
- // 定义当前单元格或行的位置
5842
- this.x = 0;
5843
- this.y = 0;
5844
- // 行高
5845
- this.rowHeight = 0;
5846
- // 列宽
5847
- this.columnWidth = 0;
5848
- // 行索引
5849
- this.rowIndex = 0;
5850
- // 列索引
5851
- this.columnIndex = 0;
5852
- // 列数
5853
- this.columnCount = 0;
5854
- this.containerWidth = 0;
5855
- }
5856
- // 用于初始化或重置布局的基本属性。这个方法通常在每次渲染新的一行或单元格时调用,确保布局信息是最新的
5857
- init({ x, y, rowIndex, columnIndex, rowHeight, columnWidth, columnCount, containerWidth }) {
5858
- this.x = x;
5859
- this.y = y;
5860
- this.rowIndex = rowIndex;
5861
- this.columnIndex = columnIndex;
5862
- this.rowHeight = rowHeight;
5863
- this.columnWidth = columnWidth;
5864
- this.columnCount = columnCount;
5865
- this.containerWidth = containerWidth;
5866
- }
5867
- // 当前单元格是否是行的第一列
5868
- get isFirst() {
5869
- return this.columnIndex === 0;
5870
- }
5871
- // 当前单元格是否是行的最后一列
5872
- get isLast() {
5873
- return this.columnIndex === this.columnCount - 1;
5874
- }
5875
- renderAddFieldBlank({ isHoverRow, isCheckedRow }) {
5876
- const rowHeight = this.rowHeight;
5877
- const fill = isCheckedRow ? this.colors.itemActiveBgColor : isHoverRow ? this.colors.gray80 : this.colors.transparent;
5878
- const addFieldBlankX = this.x + this.columnWidth + AI_TABLE_OFFSET;
5879
- this.rect({
5880
- x: addFieldBlankX,
5881
- y: this.y + AI_TABLE_OFFSET,
5882
- width: this.containerWidth - addFieldBlankX < AI_TABLE_FIELD_ADD_BUTTON_WIDTH
5883
- ? AI_TABLE_FIELD_ADD_BUTTON_WIDTH
5884
- : this.containerWidth - addFieldBlankX,
5885
- height: rowHeight,
5886
- fill
5887
- });
5888
- }
5889
- }
5890
-
5891
- class AddRowLayout extends Layout {
5892
- renderAddFieldBlank({ isHoverRow, isCheckedRow }) {
5893
- super.renderAddFieldBlank({ isHoverRow, isCheckedRow });
5894
- const rowHeight = this.rowHeight;
5895
- const defaultWidth = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
5896
- const width = this.containerWidth - this.x < defaultWidth ? defaultWidth : this.containerWidth - this.x;
5897
- this.line({
5898
- x: this.x + this.columnWidth,
5899
- y: this.y,
5900
- points: [0, rowHeight, width, rowHeight],
5901
- stroke: this.colors.gray200
5902
- });
5903
- }
5904
- renderCell({ width, isHoverRow }) {
5905
- const x = this.x;
5906
- const y = this.y;
5907
- const rowHeight = this.rowHeight;
5908
- const fill = isHoverRow ? this.colors.gray80 : this.colors.transparent;
5909
- this.rect({
5910
- x,
5911
- y: y + AI_TABLE_OFFSET,
5912
- width: width,
5913
- height: rowHeight,
5914
- fill
5915
- });
5916
- this.line({
5917
- x,
5918
- y: y + rowHeight,
5919
- points: [0, 0, width, 0],
5920
- stroke: this.colors.gray200
5921
- });
5922
- }
5923
- renderFirstCell({ isHoverRow }) {
5924
- if (!this.isFirst)
5925
- return;
5926
- const y = this.y;
5927
- const rowHeight = this.rowHeight;
5928
- const columnWidth = this.columnWidth;
5929
- const frozenOffset = AI_TABLE_OFFSET;
5930
- const fill = isHoverRow ? this.colors.gray80 : this.colors.transparent;
5931
- this.rect({
5932
- x: frozenOffset,
5933
- y: y + AI_TABLE_OFFSET,
5934
- width: columnWidth + AI_TABLE_ROW_HEAD_WIDTH - frozenOffset + 1,
5935
- height: rowHeight,
5936
- fill
5937
- });
5938
- this.line({
5939
- x: frozenOffset,
5940
- y,
5941
- points: [0, rowHeight, columnWidth + AI_TABLE_ROW_HEAD_WIDTH - frozenOffset + 1, rowHeight],
5942
- stroke: this.colors.gray200
5943
- });
5944
- this.path({
5945
- x: AI_TABLE_CELL_PADDING,
5946
- y: y + (rowHeight - AI_TABLE_ICON_COMMON_SIZE) / 2 - AI_TABLE_OFFSET,
5947
- data: AddOutlinedPath,
5948
- size: AI_TABLE_ROW_HEAD_SIZE,
5949
- fill: this.colors.gray600
5950
- });
5951
- }
5952
- renderLastCell({ isHoverRow, isCheckedRow }) {
5953
- if (!this.isLast)
5954
- return;
5955
- const width = this.columnWidth;
5956
- if (!this.isFirst) {
5957
- this.renderCell({
5958
- width,
5959
- isHoverRow
5960
- });
5961
- }
5962
- this.renderAddFieldBlank({ isHoverRow, isCheckedRow });
5963
- }
5964
- renderCommonCell({ isHoverRow }) {
5965
- if (this.isFirst || this.isLast)
5966
- return;
5967
- this.renderCell({
5968
- width: this.columnWidth,
5969
- isHoverRow
5970
- });
5971
- }
5972
- render({ isHoverRow, isCheckedRow }) {
5973
- this.renderFirstCell({
5974
- isHoverRow
5975
- });
5976
- this.renderCommonCell({
5977
- isHoverRow
5978
- });
5979
- this.renderLastCell({
5980
- isHoverRow,
5981
- isCheckedRow
5982
- });
5983
- }
5984
- }
5985
- const addRowLayout = new AddRowLayout();
5986
-
5987
5119
  // 自动生成的图标常量文件
5988
5120
  const apk = `<?xml version="1.0" encoding="UTF-8"?>
5989
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">
@@ -6326,293 +5458,1259 @@ const zip = `<?xml version="1.0" encoding="UTF-8"?>
6326
5458
  </g>
6327
5459
  </svg>`;
6328
5460
 
6329
- 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({
6330
5941
  __proto__: null,
6331
- apk: apk,
6332
- bak: bak,
6333
- bat: bat,
6334
- cs: cs,
6335
- css: css,
6336
- csv: csv,
6337
- defaultFile: defaultFile,
6338
- doc: doc,
6339
- exe: exe,
6340
- fla: fla,
6341
- html: html,
6342
- img: img,
6343
- ipa: ipa,
6344
- java: java,
6345
- js: js,
6346
- key: key,
6347
- mp3: mp3,
6348
- page: page,
6349
- pdf: pdf,
6350
- php: php,
6351
- ppt: ppt,
6352
- rar: rar,
6353
- snippet: snippet,
6354
- swf: swf,
6355
- ttf: ttf,
6356
- txt: txt,
6357
- video: video,
6358
- vss: vss,
6359
- xls: xls,
6360
- xsd: xsd,
6361
- zip: zip
5942
+ AITableCellAttachment: AITableCellAttachment,
5943
+ AITableCellLink: AITableCellLink
5944
+ });
5945
+
5946
+ const componentMap = {};
5947
+ Object.values(cellComponents).forEach((cellComponent) => {
5948
+ componentMap[cellComponent.fieldType] = cellComponent;
6362
5949
  });
6363
5950
 
6364
- function parseSVGToCanvasObjects(svgString) {
6365
- const parser = new DOMParser();
6366
- const svgDoc = parser.parseFromString(svgString, 'image/svg+xml');
6367
- const elements = svgDoc.querySelectorAll('path, polyline, polygon');
6368
- const canvasObjects = [];
6369
- elements.forEach((element) => {
6370
- let d;
6371
- if (element.tagName === 'path') {
6372
- d = element.getAttribute('d');
6373
- }
6374
- else if (element.tagName === 'polyline' || element.tagName === 'polygon') {
6375
- const points = element.getAttribute('points') || '';
6376
- const pointArray = points.split(/\s+|,/).filter(Boolean);
6377
- d = 'M' + pointArray[0] + ' ' + pointArray[1];
6378
- for (let i = 2; i < pointArray.length; i += 2) {
6379
- 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();
6380
6338
  }
6381
- if (element.tagName === 'polygon') {
6382
- 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;
6383
6437
  }
6384
- }
6385
- const fill = element.getAttribute('fill') || 'black';
6386
- const stroke = 'none';
6387
- const strokeWidth = element.getAttribute('stroke-width') || 0;
6388
- const opacity = parseFloat(element?.getAttribute('opacity') || '1');
6389
- const fillRule = element.getAttribute('fill-rule') || 'nonzero';
6390
- if (d) {
6391
- canvasObjects.push({
6392
- 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,
6393
6444
  fill,
6445
+ offsetX,
6446
+ offsetY,
6447
+ scaleX,
6448
+ scaleY,
6449
+ rotation,
6394
6450
  stroke,
6395
6451
  strokeWidth,
6396
- opacity,
6397
- 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
6398
6688
  });
6399
6689
  }
6400
- });
6401
- return canvasObjects;
6402
- }
6403
- const FileIcons = (() => {
6404
- const result = {};
6405
- Object.entries(fileIcons).forEach((fileIcon) => {
6406
- result[fileIcon[0]] = parseSVGToCanvasObjects(fileIcon[1]);
6407
- });
6408
- return result;
6409
- })();
6410
-
6411
- function getFileThumbnailName(ext) {
6412
- let result = 'defaultFile';
6413
- switch (ext) {
6414
- case 'doc':
6415
- case 'docx':
6416
- result = 'doc';
6417
- break;
6418
- case 'ppt':
6419
- case 'pptx':
6420
- result = 'ppt';
6421
- break;
6422
- case 'xls':
6423
- case 'xlsx':
6424
- result = 'xls';
6425
- break;
6426
- case 'css':
6427
- case 'scss':
6428
- case 'sass':
6429
- case 'less':
6430
- result = 'css';
6431
- break;
6432
- case 'png':
6433
- case 'jpeg':
6434
- case 'jpg':
6435
- case 'gif':
6436
- case 'bmp':
6437
- case 'svg':
6438
- result = 'img';
6439
- break;
6440
- case 'mp4':
6441
- case 'mkv':
6442
- case 'webm':
6443
- case 'mov':
6444
- case 'flv':
6445
- case '3gp':
6446
- case 'mpv':
6447
- case 'avi':
6448
- case 'mpeg':
6449
- case 'wmv':
6450
- result = 'video';
6451
- break;
6452
- case 'mp3':
6453
- case 'wma':
6454
- case 'wav':
6455
- case 'ape':
6456
- case 'flac':
6457
- case 'ogg':
6458
- case 'm4r':
6459
- case 'm4a':
6460
- result = 'mp3';
6461
- break;
6462
- case 'pdf':
6463
- case 'txt':
6464
- case 'apk':
6465
- case 'bak':
6466
- case 'cs':
6467
- case 'csv':
6468
- case 'exe':
6469
- case 'fla':
6470
- case 'html':
6471
- case 'ipa':
6472
- case 'java':
6473
- case 'js':
6474
- case 'php':
6475
- case 'rar':
6476
- case 'swf':
6477
- case 'ttf':
6478
- case 'vss':
6479
- case 'xsd':
6480
- case 'zip':
6481
- case 'youdaonote':
6482
- case 'evernote':
6483
- case 'yinxiang':
6484
- case 'quip':
6485
- case 'onenote':
6486
- case 'onedrive':
6487
- case 'box':
6488
- case 'shimo':
6489
- case 'processon':
6490
- result = ext;
6491
- break;
6492
- default:
6493
- result = 'defaultFile';
6494
- break;
6690
+ this.renderAddFieldBlank({ isHoverRow, isCheckedRow });
6495
6691
  }
6496
- return result;
6497
- }
6498
- function getFileThumbnailSvgString(ext) {
6499
- let result = 'defaultFile';
6500
- switch (ext) {
6501
- case 'doc':
6502
- case 'docx':
6503
- result = doc;
6504
- break;
6505
- case 'ppt':
6506
- case 'pptx':
6507
- result = ppt;
6508
- break;
6509
- case 'xls':
6510
- case 'xlsx':
6511
- result = xls;
6512
- break;
6513
- case 'css':
6514
- case 'scss':
6515
- case 'sass':
6516
- case 'less':
6517
- result = css;
6518
- break;
6519
- case 'png':
6520
- case 'jpeg':
6521
- case 'jpg':
6522
- case 'gif':
6523
- case 'bmp':
6524
- case 'svg':
6525
- result = img;
6526
- break;
6527
- case 'mp4':
6528
- case 'mkv':
6529
- case 'webm':
6530
- case 'mov':
6531
- case 'flv':
6532
- case '3gp':
6533
- case 'mpv':
6534
- case 'avi':
6535
- case 'mpeg':
6536
- case 'wmv':
6537
- result = video;
6538
- break;
6539
- case 'mp3':
6540
- case 'wma':
6541
- case 'wav':
6542
- case 'ape':
6543
- case 'flac':
6544
- case 'ogg':
6545
- case 'm4r':
6546
- case 'm4a':
6547
- result = mp3;
6548
- break;
6549
- case 'pdf':
6550
- result = pdf;
6551
- break;
6552
- case 'txt':
6553
- result = txt;
6554
- break;
6555
- case 'apk':
6556
- result = apk;
6557
- break;
6558
- case 'bak':
6559
- result = apk;
6560
- break;
6561
- case 'cs':
6562
- result = cs;
6563
- break;
6564
- case 'csv':
6565
- result = csv;
6566
- break;
6567
- case 'exe':
6568
- result = exe;
6569
- break;
6570
- case 'fla':
6571
- result = fla;
6572
- break;
6573
- case 'html':
6574
- result = html;
6575
- break;
6576
- case 'ipa':
6577
- result = ipa;
6578
- break;
6579
- case 'java':
6580
- result = java;
6581
- break;
6582
- case 'js':
6583
- result = js;
6584
- break;
6585
- case 'php':
6586
- result = php;
6587
- break;
6588
- case 'rar':
6589
- result = rar;
6590
- break;
6591
- case 'swf':
6592
- result = swf;
6593
- break;
6594
- case 'ttf':
6595
- result = ttf;
6596
- break;
6597
- case 'vss':
6598
- result = vss;
6599
- break;
6600
- case 'xsd':
6601
- result = xsd;
6602
- break;
6603
- case 'zip':
6604
- result = zip;
6605
- break;
6606
- default:
6607
- result = defaultFile;
6608
- 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
+ });
6609
6711
  }
6610
- return result;
6611
- }
6612
- function getFileCanvasPaths(ext) {
6613
- const fileThumbnailName = getFileThumbnailName(ext);
6614
- return FileIcons[fileThumbnailName];
6615
6712
  }
6713
+ const addRowLayout = new AddRowLayout();
6616
6714
 
6617
6715
  /**
6618
6716
  * 处理和渲染表格单元格的内容
@@ -7224,15 +7322,12 @@ class CellDrawer extends Drawer {
7224
7322
  }
7225
7323
  renderCellAttachment(render, ctx) {
7226
7324
  const { references, x, y, field, transformValue: _cellValue, rowHeight, columnWidth, isActive } = render;
7227
- const cellValue = _cellValue;
7228
- if (!cellValue?.length || !references) {
7229
- return;
7230
- }
7325
+ const cellValue = _cellValue || [];
7231
7326
  const fileIconSize = AI_TABLE_FILE_ICON_SIZE;
7232
7327
  const itemHeight = AI_TABLE_FILE_ICON_ITEM_HEIGHT;
7233
7328
  const isOperating = isActive;
7234
7329
  let currentX = AI_TABLE_CELL_PADDING;
7235
- let currentY = (AI_TABLE_ROW_BLANK_HEIGHT - fileIconSize) / 2;
7330
+ let currentY = (AI_TABLE_ROW_BLANK_HEIGHT - itemHeight) / 2;
7236
7331
  const itemOtherWidth = fileIconSize + AI_TABLE_FIELD_ITEM_MARGIN_RIGHT;
7237
7332
  const maxHeight = isActive ? 130 - AI_TABLE_CELL_MULTI_PADDING_TOP : rowHeight - AI_TABLE_CELL_MULTI_PADDING_TOP;
7238
7333
  const maxTextWidth = isOperating
@@ -7241,7 +7336,7 @@ class CellDrawer extends Drawer {
7241
7336
  const listCount = cellValue.length;
7242
7337
  let isOverflow = false;
7243
7338
  for (let index = 0; index < listCount; index++) {
7244
- const attachmentInfo = references.attachments[cellValue[index]];
7339
+ const attachmentInfo = references?.attachments[cellValue[index]];
7245
7340
  if (!attachmentInfo)
7246
7341
  continue;
7247
7342
  const { title, addition } = attachmentInfo;
@@ -8328,7 +8423,7 @@ class AITableHoverCells {
8328
8423
  };
8329
8424
  });
8330
8425
  this.hoverCellConfig = computed(() => {
8331
- const { aiTable, coordinate } = this.config();
8426
+ const { aiTable, coordinate, references, readonly } = this.config();
8332
8427
  const pointPosition = aiTable.context.pointPosition();
8333
8428
  const hoverCell = this.hoverCell();
8334
8429
  if (!hoverCell) {
@@ -8336,10 +8431,7 @@ class AITableHoverCells {
8336
8431
  }
8337
8432
  const { field, recordId, fieldId, renderComponentDefinition } = hoverCell;
8338
8433
  const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, field._id]);
8339
- const transformValue = transformCellValue(aiTable, field, cellValue) || {};
8340
- if (Object.keys(transformValue).length === 0) {
8341
- return;
8342
- }
8434
+ const transformValue = transformCellValue(aiTable, field, cellValue);
8343
8435
  const { rowHeight, columnCount, rowCount } = coordinate;
8344
8436
  const columnIndex = pointPosition.columnIndex;
8345
8437
  const rowIndex = pointPosition.rowIndex;
@@ -8361,10 +8453,12 @@ class AITableHoverCells {
8361
8453
  const renderY = 0 - AI_TABLE_OFFSET * 2;
8362
8454
  const result = {
8363
8455
  field,
8456
+ recordId,
8364
8457
  aiTable,
8365
8458
  coordinate,
8366
8459
  x,
8367
8460
  y,
8461
+ readonly,
8368
8462
  render: {
8369
8463
  aiTable,
8370
8464
  recordId,
@@ -8376,7 +8470,8 @@ class AITableHoverCells {
8376
8470
  rowHeight,
8377
8471
  cellValue,
8378
8472
  transformValue,
8379
- style
8473
+ style,
8474
+ references
8380
8475
  }
8381
8476
  };
8382
8477
  return result;
@@ -9006,17 +9101,17 @@ class AITableGrid extends AITableGridBase {
9006
9101
  case AI_TABLE_ROW_ADD_BUTTON: {
9007
9102
  this.aiTableGridSelectionService.clearSelection();
9008
9103
  this.addRecord();
9009
- return;
9104
+ break;
9010
9105
  }
9011
9106
  case AI_TABLE_ROW_SELECT_CHECKBOX: {
9012
9107
  const pointRecordId = context.linearRows()[pointRowIndex]?._id;
9013
9108
  this.selectRecord(pointRecordId);
9014
- return;
9109
+ break;
9015
9110
  }
9016
9111
  case AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX: {
9017
9112
  const isChecked = this.aiTable.selection().selectAllState === AITableSelectAllState.all;
9018
9113
  this.toggleSelectAll(!isChecked);
9019
- return;
9114
+ break;
9020
9115
  }
9021
9116
  case AI_TABLE_FIELD_ADD_BUTTON: {
9022
9117
  this.aiTableGridSelectionService.clearSelection();
@@ -9026,7 +9121,7 @@ class AITableGrid extends AITableGridBase {
9026
9121
  x: fieldGroupRect.x + containerRect.x,
9027
9122
  y: containerRect.y + fieldGroupRect.y + fieldGroupRect.height
9028
9123
  });
9029
- return;
9124
+ break;
9030
9125
  }
9031
9126
  case AI_TABLE_FIELD_HEAD_MORE:
9032
9127
  mouseEvent.preventDefault();
@@ -9054,36 +9149,52 @@ class AITableGrid extends AITableGridBase {
9054
9149
  editFieldPosition
9055
9150
  });
9056
9151
  }
9057
- return;
9152
+ break;
9058
9153
  }
9154
+ const targetNameDetail = getDetailByTargetName(e.event.target.name());
9155
+ this.aiClick.emit({
9156
+ ...e,
9157
+ targetNameDetail
9158
+ });
9159
+ return;
9059
9160
  }
9060
9161
  stageDblclick(e) {
9162
+ const _targetName = e.event.target.name();
9163
+ const targetNameDetail = getDetailByTargetName(_targetName);
9061
9164
  if (this.aiReadonly()) {
9165
+ this.aiDbClick.emit({
9166
+ ...e,
9167
+ targetNameDetail
9168
+ });
9062
9169
  return;
9063
9170
  }
9064
- const _targetName = e.event.target.name();
9065
- const { fieldId, recordId } = getDetailByTargetName(_targetName);
9171
+ const { fieldId, recordId } = targetNameDetail;
9066
9172
  if (!recordId || !fieldId) {
9067
9173
  return;
9068
9174
  }
9069
9175
  const field = this.aiTable.fieldsMap()[fieldId];
9070
9176
  const fieldType = field.type;
9071
- if (!DBL_CLICK_EDIT_TYPE.includes(fieldType)) {
9072
- 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);
9073
9191
  }
9074
- setTimeout(() => {
9075
- this.aiTableGridEventService.openCellEditor(this.aiTable, {
9076
- viewContainerRef: this.viewContainerRef,
9077
- container: this.containerElement(),
9078
- coordinate: this.coordinate(),
9079
- fieldId: fieldId,
9080
- recordId: recordId,
9081
- references: this.aiReferences(),
9082
- updateFieldValue: (value) => {
9083
- this.aiUpdateFieldValue.emit(value);
9084
- }
9192
+ else {
9193
+ this.aiDbClick.emit({
9194
+ ...e,
9195
+ targetNameDetail
9085
9196
  });
9086
- }, 0);
9197
+ }
9087
9198
  }
9088
9199
  bindWheel() {
9089
9200
  fromEvent(this.containerElement(), 'wheel', { passive: false })
@@ -9233,7 +9344,7 @@ class AITableGrid extends AITableGridBase {
9233
9344
  });
9234
9345
  }
9235
9346
  handleFieldDragStart() {
9236
- if (this.aiTableGridSelectionService.selectedFields.size > 0) {
9347
+ if (!this.aiReadonly() && this.aiTableGridSelectionService.selectedFields.size > 0) {
9237
9348
  this.aiTableGridSelectionService.drag({
9238
9349
  type: DragType.field,
9239
9350
  sourceIds: this.aiTableGridSelectionService.selectedFields,
@@ -9282,5 +9393,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
9282
9393
  * Generated bundle index. Do not edit.
9283
9394
  */
9284
9395
 
9285
- 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 };
9286
9397
  //# sourceMappingURL=ai-table-grid.mjs.map