@ai-table/grid 0.0.45 → 0.0.47

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 (44) hide show
  1. package/components/drag/drag.component.d.ts +5 -0
  2. package/components/drag/drag.component.d.ts.map +1 -1
  3. package/components/drag/drag.component.scss +1 -1
  4. package/components/field-setting/field-setting.component.d.ts.map +1 -1
  5. package/constants/table.d.ts +1 -0
  6. package/constants/table.d.ts.map +1 -1
  7. package/core/types/core.d.ts +7 -2
  8. package/core/types/core.d.ts.map +1 -1
  9. package/esm2022/components/drag/drag.component.mjs +75 -4
  10. package/esm2022/components/field-setting/field-setting.component.mjs +3 -2
  11. package/esm2022/constants/table.mjs +2 -1
  12. package/esm2022/core/types/core.mjs +1 -1
  13. package/esm2022/core/utils/queries.mjs +2 -2
  14. package/esm2022/dom-grid.component.mjs +3 -3
  15. package/esm2022/grid-base.component.mjs +6 -3
  16. package/esm2022/grid.component.mjs +24 -2
  17. package/esm2022/renderer/components/field-head.component.mjs +18 -2
  18. package/esm2022/services/selection.service.mjs +4 -1
  19. package/esm2022/types/grid.mjs +1 -1
  20. package/esm2022/utils/build.mjs +2 -3
  21. package/esm2022/utils/cell.mjs +3 -2
  22. package/esm2022/utils/clipboard/extract.mjs +29 -10
  23. package/esm2022/utils/clipboard/paste.mjs +1 -7
  24. package/esm2022/utils/field/model/link.mjs +3 -3
  25. package/esm2022/utils/field/model/select.mjs +31 -9
  26. package/fesm2022/ai-table-grid.mjs +186 -36
  27. package/fesm2022/ai-table-grid.mjs.map +1 -1
  28. package/grid-base.component.d.ts +5 -3
  29. package/grid-base.component.d.ts.map +1 -1
  30. package/grid.component.d.ts.map +1 -1
  31. package/package.json +1 -1
  32. package/renderer/components/field-head.component.d.ts +8 -0
  33. package/renderer/components/field-head.component.d.ts.map +1 -1
  34. package/services/selection.service.d.ts +2 -1
  35. package/services/selection.service.d.ts.map +1 -1
  36. package/types/grid.d.ts +2 -1
  37. package/types/grid.d.ts.map +1 -1
  38. package/utils/build.d.ts.map +1 -1
  39. package/utils/cell.d.ts.map +1 -1
  40. package/utils/clipboard/extract.d.ts +1 -1
  41. package/utils/clipboard/extract.d.ts.map +1 -1
  42. package/utils/clipboard/paste.d.ts.map +1 -1
  43. package/utils/field/model/select.d.ts +1 -1
  44. package/utils/field/model/select.d.ts.map +1 -1
@@ -44,6 +44,7 @@ import { ThyProgress } from 'ngx-tethys/progress';
44
44
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
45
45
  import { LRUCache } from 'lru-cache';
46
46
  import { fromUnixTime, subDays } from 'date-fns';
47
+ import { DEFAULT_COLORS } from 'ngx-tethys/color-picker';
47
48
  import Konva from 'konva';
48
49
  import { Shape } from 'konva/lib/Shape';
49
50
  import { Sprite } from 'konva/lib/shapes/Sprite';
@@ -920,7 +921,7 @@ const AITableQueries = {
920
921
  if (!path) {
921
922
  throw new Error(`path does not exist as path [${path}]`);
922
923
  }
923
- return aiTable.fields().find((item) => item._id === path[0]);
924
+ return aiTable.gridData().fields.find((item) => item._id === path[0]);
924
925
  },
925
926
  getRecord(aiTable, path) {
926
927
  if (!aiTable) {
@@ -1691,8 +1692,9 @@ class AITableFieldSetting {
1691
1692
  this.aiEditField().type === AITableFieldType.member && !!this.aiEditField().settings?.is_multiple;
1692
1693
  }
1693
1694
  selectFieldType(field) {
1695
+ const fieldsSizeMap = this.aiTable().gridData().fieldsSizeMap;
1694
1696
  this.aiEditField.update((item) => {
1695
- const width = item.width ?? field.width;
1697
+ const width = fieldsSizeMap[item._id] ?? field.width;
1696
1698
  const settings = field.settings || {};
1697
1699
  const name = createDefaultFieldName(this.aiTable(), field);
1698
1700
  return { ...item, ...field, width, name, settings };
@@ -1805,6 +1807,9 @@ class AITableGridSelectionService {
1805
1807
  drag(config) {
1806
1808
  this.aiTable.dragState.set(config);
1807
1809
  }
1810
+ getDragStateType() {
1811
+ return this.aiTable.dragState?.()?.type;
1812
+ }
1808
1813
  clearDrag() {
1809
1814
  this.aiTable.dragState.set({
1810
1815
  type: DragType.none,
@@ -1973,6 +1978,7 @@ const AI_TABLE_FIELD_ADD_BUTTON = 'AI_TABLE_FIELD_ADD_BUTTON'; // 添加列名
1973
1978
  const AI_TABLE_FIELD_ADD_BUTTON_WIDTH = 100; // 添加列宽度
1974
1979
  const AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE = 8; // 字段表列头图标的间距
1975
1980
  const AI_TABLE_FIELD_HEAD_MORE = 'AI_TABLE_FIELD_HEAD_MORE'; // 更多图标名称
1981
+ const AI_TABLE_FIELD_HEAD_OPACITY_LINE = 'AI_TABLE_FIELD_HEAD_OPACITY_LINE'; // 字段列头透明线
1976
1982
  const AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS = '.ai-table-prevent-clear-selection';
1977
1983
  const AI_TABLE_ICON_COMMON_SIZE = 16; // 表格图标的通用尺寸
1978
1984
  const AI_TABLE_CELL = 'AI_TABLE_CELL'; // 单元格标识
@@ -2168,8 +2174,7 @@ const buildGridData = (aiTable, recordValue, fieldsValue) => {
2168
2174
  const fieldOption = fieldOptions.find((item) => item.type === value.type);
2169
2175
  return {
2170
2176
  ...value,
2171
- icon: value.icon || fieldOption.icon,
2172
- width: value.width || fieldOption.width
2177
+ icon: value.icon || fieldOption.icon
2173
2178
  };
2174
2179
  });
2175
2180
  return {
@@ -2231,9 +2236,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2231
2236
  }], ctorParameters: () => [{ type: i1$1.ThyPopover }] });
2232
2237
 
2233
2238
  function getColumnIndicesSizeMap(aiTable, fields) {
2239
+ const fieldSizeMap = aiTable.gridData().fieldsSizeMap;
2234
2240
  const columnIndicesSizeMap = {};
2235
2241
  fields?.forEach((field, index) => {
2236
- columnIndicesSizeMap[index] = field.width ?? getFieldOptionByField(aiTable, field).width;
2242
+ columnIndicesSizeMap[index] = fieldSizeMap[field._id] ?? getFieldOptionByField(aiTable, field).width;
2237
2243
  });
2238
2244
  return columnIndicesSizeMap;
2239
2245
  }
@@ -2608,22 +2614,41 @@ const readFromClipboard = async () => {
2608
2614
  };
2609
2615
 
2610
2616
  function extractText(text) {
2611
- let plainText = text;
2617
+ if (!text)
2618
+ return '';
2619
+ // 如果文本包含HTML链接标签,提取链接文本
2612
2620
  if (text.includes('<a')) {
2613
2621
  const aTagMatch = text.match(/<a[^>]*>(.*?)<\/a>/i);
2614
- if (aTagMatch && aTagMatch[1] && aTagMatch[1].trim()) {
2615
- plainText = aTagMatch[1];
2622
+ if (aTagMatch?.[1]?.trim()) {
2623
+ return aTagMatch[1].trim();
2616
2624
  }
2617
2625
  }
2618
- return plainText;
2626
+ return text;
2619
2627
  }
2620
- function extractLinkHref(text) {
2621
- let href = null;
2628
+ function extractLinkUrl(text) {
2629
+ if (!text)
2630
+ return null;
2631
+ // 1. 从HTML链接标签中提取URL,比如 https://mail.qq.com
2622
2632
  const hrefMatch = text.match(/href="([^"]+)"/);
2623
- if (hrefMatch && hrefMatch[1] && hrefMatch[1].trim()) {
2624
- href = hrefMatch[1];
2633
+ if (hrefMatch?.[1]) {
2634
+ return hrefMatch[1];
2635
+ }
2636
+ // 2. 匹配完整的URL(带协议),比如 https://mail.qq.com
2637
+ const protocolAndDomainMatch = text.match(/^(?:\w+:)?\/\/(\S+)$/);
2638
+ if (protocolAndDomainMatch?.[0]) {
2639
+ return protocolAndDomainMatch[0];
2625
2640
  }
2626
- return href;
2641
+ // 3. 匹配localhost格式,比如 localhost:6100
2642
+ const localhostDomainMatch = text.match(/^localhost[\:?\d]*(?:[^\:?\d]\S*)?$/);
2643
+ if (localhostDomainMatch?.[0]) {
2644
+ return `http://${localhostDomainMatch[0]}`;
2645
+ }
2646
+ // 4. 匹配普通域名,比如 www.baidu.com
2647
+ const ordinaryDomainMatch = text.match(/^[^\s\.]+\.\S{2,}$/);
2648
+ if (ordinaryDomainMatch?.[0]) {
2649
+ return `http://${ordinaryDomainMatch[0]}`;
2650
+ }
2651
+ return null;
2627
2652
  }
2628
2653
 
2629
2654
  const zhIntlCollator = typeof Intl !== 'undefined' ? new Intl.Collator('zh-CN') : undefined;
@@ -2926,7 +2951,7 @@ function toLinkFieldValue(plainText, targetField, originData) {
2926
2951
  }
2927
2952
  }
2928
2953
  else {
2929
- const url = extractLinkHref(plainText);
2954
+ const url = extractLinkUrl(plainText);
2930
2955
  const text = extractText(plainText);
2931
2956
  if (url && text) {
2932
2957
  return {
@@ -3257,6 +3282,7 @@ function toSelectFieldValue(plainText, targetField, originData) {
3257
3282
  }
3258
3283
  function processPastedValueForSelect(plainText, targetField, originData) {
3259
3284
  const targetFieldOptions = targetField.settings?.options || [];
3285
+ const targetOptionStyle = targetField.settings?.option_style || AITableSelectOptionStyle.text;
3260
3286
  let existOptionIds = [];
3261
3287
  let newOptions = [];
3262
3288
  let cellFullTexts = plainText.split(',').map((text) => text.trim());
@@ -3276,12 +3302,8 @@ function processPastedValueForSelect(plainText, targetField, originData) {
3276
3302
  else {
3277
3303
  const originOption = originOptionsMap[id];
3278
3304
  if (originOption) {
3279
- newOptions.push({
3280
- text: originOption.text,
3281
- icon: originOption.icon,
3282
- color: originOption.color,
3283
- bg_color: originOption.bg_color
3284
- });
3305
+ const newOption = copyOption(originOption, targetFieldOptions, targetOptionStyle);
3306
+ newOptions.push(newOption);
3285
3307
  }
3286
3308
  }
3287
3309
  });
@@ -3290,7 +3312,14 @@ function processPastedValueForSelect(plainText, targetField, originData) {
3290
3312
  else {
3291
3313
  cellFullTexts.forEach((text) => {
3292
3314
  const option = targetFieldOptions.find((option) => option.text === text);
3293
- option ? existOptionIds.push(option._id) : newOptions.push({ text });
3315
+ if (option) {
3316
+ existOptionIds.push(option._id);
3317
+ }
3318
+ else {
3319
+ const originOption = { text };
3320
+ const newOption = copyOption(originOption, targetFieldOptions, targetOptionStyle);
3321
+ newOptions.push(newOption);
3322
+ }
3294
3323
  });
3295
3324
  }
3296
3325
  const isMultiple = targetField.settings?.is_multiple;
@@ -3311,6 +3340,22 @@ function processPastedValueForSelect(plainText, targetField, originData) {
3311
3340
  }
3312
3341
  }
3313
3342
  }
3343
+ function copyOption(originOption, targetFieldOptions, targetOptionStyle) {
3344
+ let newOption = {
3345
+ _id: idCreator(),
3346
+ text: originOption.text
3347
+ };
3348
+ if (targetOptionStyle !== AITableSelectOptionStyle.text) {
3349
+ const originBgColor = originOption.bg_color;
3350
+ const existBgColors = targetFieldOptions.map((option) => option.bg_color);
3351
+ const defaultBgColor = DEFAULT_COLORS[10 + (targetFieldOptions?.length || 0)];
3352
+ newOption = {
3353
+ ...newOption,
3354
+ bg_color: originBgColor && !existBgColors.includes(originBgColor) ? originBgColor : defaultBgColor
3355
+ };
3356
+ }
3357
+ return newOption;
3358
+ }
3314
3359
  function cellValueToSortValue$1(cellValue, field) {
3315
3360
  if (!cellValue) {
3316
3361
  return null;
@@ -3558,12 +3603,6 @@ function getPasteValue(plainText, aiTableContent, recordIndex, fieldIndex, targe
3558
3603
  let newField = null;
3559
3604
  let newOptionIds = [];
3560
3605
  if (newOptions.length) {
3561
- newOptions = newOptions.map((option) => {
3562
- return {
3563
- ...option,
3564
- _id: idCreator()
3565
- };
3566
- });
3567
3606
  newField = {
3568
3607
  ...targetField,
3569
3608
  settings: {
@@ -6342,6 +6381,7 @@ class AITableGridBase {
6342
6381
  constructor() {
6343
6382
  this.aiRecords = model.required();
6344
6383
  this.aiFields = model.required();
6384
+ this.aiFieldsSizeMap = model.required();
6345
6385
  this.aiContextMenuItems = input();
6346
6386
  this.aiFieldConfig = input();
6347
6387
  this.aiReadonly = input();
@@ -6361,6 +6401,7 @@ class AITableGridBase {
6361
6401
  this.aiMoveField = output();
6362
6402
  this.aiUpdateFieldValue = output();
6363
6403
  this.aiSetField = output();
6404
+ this.aiSetFieldWidth = output();
6364
6405
  this.aiClick = output();
6365
6406
  this.aiDbClick = output();
6366
6407
  this.fieldMenus = computed(() => {
@@ -6376,7 +6417,8 @@ class AITableGridBase {
6376
6417
  }
6377
6418
  return {
6378
6419
  records: this.aiRecords(),
6379
- fields: this.aiFields()
6420
+ fields: this.aiFields(),
6421
+ fieldsSizeMap: this.aiFieldsSizeMap()
6380
6422
  };
6381
6423
  });
6382
6424
  this.ngZone = inject(NgZone);
@@ -6484,7 +6526,7 @@ class AITableGridBase {
6484
6526
  }
6485
6527
  }
6486
6528
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6487
- 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 }, aiGetI18nTextByKey: { classPropertyName: "aiGetI18nTextByKey", publicName: "aiGetI18nTextByKey", 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 }); }
6529
+ 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 }, aiFieldsSizeMap: { classPropertyName: "aiFieldsSizeMap", publicName: "aiFieldsSizeMap", isSignal: true, isRequired: true, transformFunction: null }, aiContextMenuItems: { classPropertyName: "aiContextMenuItems", publicName: "aiContextMenuItems", isSignal: true, isRequired: false, transformFunction: null }, aiFieldConfig: { classPropertyName: "aiFieldConfig", publicName: "aiFieldConfig", isSignal: true, isRequired: false, transformFunction: null }, aiReadonly: { classPropertyName: "aiReadonly", publicName: "aiReadonly", isSignal: true, isRequired: false, transformFunction: null }, aiPlugins: { classPropertyName: "aiPlugins", publicName: "aiPlugins", isSignal: true, isRequired: false, transformFunction: null }, aiReferences: { classPropertyName: "aiReferences", publicName: "aiReferences", isSignal: true, isRequired: true, transformFunction: null }, aiBuildRenderDataFn: { classPropertyName: "aiBuildRenderDataFn", publicName: "aiBuildRenderDataFn", isSignal: true, isRequired: false, transformFunction: null }, aiGetI18nTextByKey: { classPropertyName: "aiGetI18nTextByKey", publicName: "aiGetI18nTextByKey", isSignal: true, isRequired: false, transformFunction: null }, aiKeywords: { classPropertyName: "aiKeywords", publicName: "aiKeywords", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiRecords: "aiRecordsChange", aiFields: "aiFieldsChange", aiFieldsSizeMap: "aiFieldsSizeMapChange", aiTableInitialized: "aiTableInitialized", aiAddRecord: "aiAddRecord", aiAddField: "aiAddField", aiMoveField: "aiMoveField", aiUpdateFieldValue: "aiUpdateFieldValue", aiSetField: "aiSetField", aiSetFieldWidth: "aiSetFieldWidth", aiClick: "aiClick", aiDbClick: "aiDbClick" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6488
6530
  }
6489
6531
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, decorators: [{
6490
6532
  type: Component,
@@ -6511,7 +6553,7 @@ class AITableDomGrid extends AITableGridBase {
6511
6553
  });
6512
6554
  }
6513
6555
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
6514
- 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 }); }
6556
+ 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: gridData().fieldsSizeMap[field._id] + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"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: gridData().fieldsSizeMap[field._id] + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SelectOptionPipe, name: "selectOption" }, { kind: "pipe", type: SelectOptionsPipe, name: "selectOptions" }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "ngmodule", type: ThyPopoverModule }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyRate, selector: "thy-rate", inputs: ["thyCount", "thyDisabled", "thyAllowHalf", "thyAllowClear", "thyTooltips", "thyIconTemplate"], outputs: ["thyItemHoverChange"] }, { kind: "component", type: ThyProgress, selector: "thy-progress", inputs: ["thyType", "thySize", "thyValue", "thyMax", "thyTips", "thyShape", "thyGapDegree", "thyGapPosition", "thyStrokeWidth"] }, { kind: "pipe", type: ThyDatePickerFormatPipe, name: "thyDatePickerFormat" }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyCheckboxModule }, { kind: "component", type: i3$1.ThyCheckbox, selector: "thy-checkbox,[thy-checkbox],[thyCheckbox]", inputs: ["thyIndeterminate"] }, { kind: "ngmodule", type: ThyAvatarModule }, { kind: "component", type: i4.ThyAvatar, selector: "thy-avatar", inputs: ["thyShowName", "thySrc", "thyName", "thySize", "thyShowRemove", "thyRemovable", "thyImgClass", "thyDisabled", "thyLoading", "thyFetchPriority"], outputs: ["thyOnRemove", "thyRemove", "thyError"] }, { 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 }); }
6515
6557
  }
6516
6558
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, decorators: [{
6517
6559
  type: Component,
@@ -6547,7 +6589,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
6547
6589
  UserPipe,
6548
6590
  SelectSettingPipe,
6549
6591
  MemberSettingPipe
6550
- ], 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" }]
6592
+ ], 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: gridData().fieldsSizeMap[field._id] + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"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: gridData().fieldsSizeMap[field._id] + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n" }]
6551
6593
  }] });
6552
6594
 
6553
6595
  class AITableIcon {
@@ -8003,6 +8045,20 @@ class AITableFieldHead {
8003
8045
  cornerRadius: 4
8004
8046
  };
8005
8047
  });
8048
+ this.fieldOpacityLineConfig = computed(() => {
8049
+ const { field, width, height } = this.config();
8050
+ return {
8051
+ x: AI_TABLE_OFFSET + width,
8052
+ y: AI_TABLE_OFFSET,
8053
+ name: generateTargetName({
8054
+ targetName: AI_TABLE_FIELD_HEAD_OPACITY_LINE,
8055
+ fieldId: field._id
8056
+ }),
8057
+ points: [0, 0, 0, height],
8058
+ stroke: Colors.transparent,
8059
+ strokeWidth: 6
8060
+ };
8061
+ });
8006
8062
  }
8007
8063
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableFieldHead, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8008
8064
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableFieldHead, isStandalone: true, selector: "ai-table-field-head", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
@@ -8015,6 +8071,7 @@ class AITableFieldHead {
8015
8071
  <ai-table-icon [config]="moreIconConfig()"></ai-table-icon>
8016
8072
  }
8017
8073
  </ko-group>
8074
+ <ko-line [config]="fieldOpacityLineConfig()"></ko-line>
8018
8075
  </ko-group>
8019
8076
  `, 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: AITableFieldIcon, selector: "ai-table-field-icon", inputs: ["config"] }, { kind: "component", type: AITableText, selector: "ai-table-text", inputs: ["config"], outputs: ["koClick", "koMouseMove"] }, { kind: "component", type: AITableIcon, selector: "ai-table-icon", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8020
8077
  }
@@ -8032,6 +8089,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
8032
8089
  <ai-table-icon [config]="moreIconConfig()"></ai-table-icon>
8033
8090
  }
8034
8091
  </ko-group>
8092
+ <ko-line [config]="fieldOpacityLineConfig()"></ko-line>
8035
8093
  </ko-group>
8036
8094
  `,
8037
8095
  standalone: true,
@@ -8845,12 +8903,15 @@ class AITableDragComponent {
8845
8903
  initElements() {
8846
8904
  this.rect = this.elementRef.nativeElement.querySelector('.rect');
8847
8905
  this.auxiliaryLine = this.elementRef.nativeElement.querySelector('.auxiliary-line');
8906
+ this.colResizeLine = this.elementRef.nativeElement.querySelector('.col-resize-line');
8848
8907
  }
8849
8908
  setupEventListeners() {
8850
8909
  this.mousedownListener = this.render2.listen('window', 'mousedown', (e) => {
8851
8910
  this.mouseStartPosition = { x: e.x, y: e.y };
8911
+ e.preventDefault();
8852
8912
  });
8853
8913
  this.mousemoveListener = this.render2.listen('window', 'mousemove', (e) => {
8914
+ e.preventDefault();
8854
8915
  if (this.timer) {
8855
8916
  cancelAnimationFrame(this.timer);
8856
8917
  }
@@ -8868,10 +8929,17 @@ class AITableDragComponent {
8868
8929
  }
8869
8930
  handleDragStateChange() {
8870
8931
  const drag = this.aiTableGridSelectionService.aiTable.dragState?.();
8871
- if (!drag || drag.type === DragType.none || !this.rect || !this.auxiliaryLine) {
8932
+ if (!drag) {
8872
8933
  this.aiTableDrag = null;
8873
8934
  return;
8874
8935
  }
8936
+ if (drag.type === DragType.none || !this.rect || !this.auxiliaryLine) {
8937
+ return;
8938
+ }
8939
+ if (drag.type === DragType.columnWidth) {
8940
+ this.setDisplayStyle('block');
8941
+ this.showColResize(drag);
8942
+ }
8875
8943
  this.aiTableDrag = drag;
8876
8944
  }
8877
8945
  handleDrag(e, drag) {
@@ -8887,6 +8955,7 @@ class AITableDragComponent {
8887
8955
  case DragType.record:
8888
8956
  break;
8889
8957
  case DragType.columnWidth:
8958
+ this.movingColumnWidth(drag, moveX);
8890
8959
  break;
8891
8960
  }
8892
8961
  }
@@ -8947,6 +9016,58 @@ class AITableDragComponent {
8947
9016
  this.draggedData = null;
8948
9017
  }
8949
9018
  }
9019
+ movingColumnWidth(drag, moveX) {
9020
+ const aiTable = this.aiTableGridSelectionService.aiTable;
9021
+ const visibleColumnIndexMap = aiTable.context.visibleColumnsIndexMap();
9022
+ const sourceColumnIndex = visibleColumnIndexMap.get(drag.sourceIds.values().next().value) || 0;
9023
+ const sourceColumnStartX = drag.coordinate.getColumnOffset(sourceColumnIndex);
9024
+ const sourceColumnWidth = drag.coordinate.getColumnWidth(sourceColumnIndex);
9025
+ const scroll = drag.scroll || { x: 0, y: 0 };
9026
+ const pointerX = moveX + sourceColumnStartX;
9027
+ const colResizeX = pointerX - (sourceColumnIndex === 0 ? 0 : scroll.x);
9028
+ const left = `${colResizeX + sourceColumnWidth}px`;
9029
+ this.setAuxiliaryLineStyles({
9030
+ width: '2px',
9031
+ height: '100%',
9032
+ top: '0',
9033
+ left
9034
+ });
9035
+ this.draggedData = {
9036
+ type: DragType.columnWidth,
9037
+ fieldIds: drag.sourceIds,
9038
+ width: Math.max(MIN_COLUMN_WIDTH, sourceColumnWidth + moveX)
9039
+ };
9040
+ }
9041
+ showColResize(drag) {
9042
+ const aiTable = this.aiTableGridSelectionService.aiTable;
9043
+ const visibleColumnIndexMap = aiTable.context.visibleColumnsIndexMap();
9044
+ const sourceColumnIndex = visibleColumnIndexMap.get(drag.sourceIds.values().next().value) || 0;
9045
+ const coordinate = drag.coordinate;
9046
+ const sourceColumnStartX = coordinate.getColumnOffset(sourceColumnIndex);
9047
+ const scroll = drag.scroll || { x: 0, y: 0 };
9048
+ let targetColumnIndex = coordinate.getColumnStartIndex(sourceColumnStartX + scroll.x);
9049
+ let targetColumnStartX = coordinate.getColumnOffset(targetColumnIndex);
9050
+ const sourceColumnWidth = drag.coordinate.getColumnWidth(sourceColumnIndex);
9051
+ const opacityLineWidth = 4;
9052
+ // 重置样式
9053
+ this.setRectStyles({ width: 0 });
9054
+ this.resetAuxiliaryLine();
9055
+ this.setDisplayStyle('block');
9056
+ this.render2.setStyle(this.elementRef.nativeElement, 'cursor', 'col-resize');
9057
+ // 隐藏列宽调整线,用于监听鼠标离开此区域后结束宽度调整
9058
+ this.setColResizeLine({
9059
+ opacity: 0,
9060
+ height: '100%',
9061
+ width: `${opacityLineWidth}px`,
9062
+ left: `${targetColumnStartX + sourceColumnWidth - opacityLineWidth / 2}px`,
9063
+ zIndex: 10
9064
+ });
9065
+ this.lineMouseLeaveListener = this.render2.listen(this.colResizeLine, 'mouseleave', () => {
9066
+ this.setDisplayStyle('none');
9067
+ this.lineMouseLeaveListener?.();
9068
+ this.lineMouseLeaveListener = undefined;
9069
+ });
9070
+ }
8950
9071
  handleDragEnd() {
8951
9072
  this.setDisplayStyle('none');
8952
9073
  if (this.draggedData) {
@@ -8976,6 +9097,11 @@ class AITableDragComponent {
8976
9097
  this.render2.setStyle(this.auxiliaryLine, prop, value);
8977
9098
  });
8978
9099
  }
9100
+ setColResizeLine(styles) {
9101
+ Object.entries(styles).forEach(([prop, value]) => {
9102
+ this.render2.setStyle(this.colResizeLine, prop, value);
9103
+ });
9104
+ }
8979
9105
  resetAuxiliaryLine() {
8980
9106
  this.setAuxiliaryLineStyles({ width: 0 });
8981
9107
  }
@@ -8986,19 +9112,21 @@ class AITableDragComponent {
8986
9112
  this.mousemoveListener();
8987
9113
  if (this.mouseupListener)
8988
9114
  this.mouseupListener();
9115
+ if (this.lineMouseLeaveListener)
9116
+ this.lineMouseLeaveListener();
8989
9117
  if (this.timer) {
8990
9118
  cancelAnimationFrame(this.timer);
8991
9119
  this.timer = null;
8992
9120
  }
8993
9121
  }
8994
9122
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDragComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8995
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AITableDragComponent, isStandalone: true, selector: "ai-table-drag", outputs: { dragEnd: "dragEnd" }, host: { classAttribute: "drag-container" }, ngImport: i0, template: "<div class=\"rect\"></div>\n<div class=\"auxiliary-line\"></div>", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9123
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AITableDragComponent, isStandalone: true, selector: "ai-table-drag", outputs: { dragEnd: "dragEnd" }, host: { classAttribute: "drag-container" }, ngImport: i0, template: "<div class=\"rect\"></div>\n<div class=\"auxiliary-line\"></div>\n<div class=\"col-resize-line\"></div>", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8996
9124
  }
8997
9125
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDragComponent, decorators: [{
8998
9126
  type: Component,
8999
9127
  args: [{ selector: 'ai-table-drag', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
9000
9128
  class: 'drag-container'
9001
- }, template: "<div class=\"rect\"></div>\n<div class=\"auxiliary-line\"></div>" }]
9129
+ }, template: "<div class=\"rect\"></div>\n<div class=\"auxiliary-line\"></div>\n<div class=\"col-resize-line\"></div>" }]
9002
9130
  }], ctorParameters: () => [] });
9003
9131
 
9004
9132
  class AITableGrid extends AITableGridBase {
@@ -9196,6 +9324,18 @@ class AITableGrid extends AITableGridBase {
9196
9324
  }
9197
9325
  }
9198
9326
  }
9327
+ const { targetName: _targetName, fieldId } = getDetailByTargetName(targetName);
9328
+ if (_targetName === AI_TABLE_FIELD_HEAD_OPACITY_LINE && fieldId) {
9329
+ this.aiTableGridSelectionService.drag({
9330
+ type: DragType.columnWidth,
9331
+ sourceIds: new Set([fieldId]),
9332
+ scroll: this.getScrollPosition(),
9333
+ coordinate: this.coordinate()
9334
+ });
9335
+ }
9336
+ else if (this.aiTableGridSelectionService.getDragStateType() === DragType.columnWidth) {
9337
+ this.aiTableGridSelectionService.clearDrag();
9338
+ }
9199
9339
  });
9200
9340
  }
9201
9341
  stageMousedown(e) {
@@ -9482,6 +9622,9 @@ class AITableGrid extends AITableGridBase {
9482
9622
  fromEvent(document, 'keydown')
9483
9623
  .pipe(filter((event) => (event.ctrlKey || event.metaKey) && (event.key === 'c' || event.key === 'v')), takeUntilDestroyed(this.destroyRef))
9484
9624
  .subscribe(async (event) => {
9625
+ if (this.aiReadonly()) {
9626
+ return;
9627
+ }
9485
9628
  const hasSelectedCells = this.aiTable.selection().selectedCells.size > 0;
9486
9629
  if (!hasSelectedCells) {
9487
9630
  return;
@@ -9555,6 +9698,13 @@ class AITableGrid extends AITableGridBase {
9555
9698
  }
9556
9699
  break;
9557
9700
  case DragType.columnWidth:
9701
+ if (data.fieldIds && isNumber(data.width)) {
9702
+ const fieldId = data.fieldIds.values().next().value;
9703
+ this.aiSetFieldWidth.emit({
9704
+ path: [fieldId],
9705
+ width: data.width
9706
+ });
9707
+ }
9558
9708
  break;
9559
9709
  case DragType.record:
9560
9710
  return;
@@ -9575,5 +9725,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
9575
9725
  * Generated bundle index. Do not edit.
9576
9726
  */
9577
9727
 
9578
- export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsSameOptionPipe, AITableFieldSetting, AITableFieldType, AITableFilterOperation, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridI18nKey, 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, 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, generateNewName, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getDefaultFieldValue, getDefaultI18nTextByKey, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getFieldOptions, getFieldValue, getHoverCell, getHoverEditorBoxOffset, getHoverEditorSpace, getI18nTextByKey, 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 };
9728
+ export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsSameOptionPipe, AITableFieldSetting, AITableFieldType, AITableFilterOperation, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridI18nKey, 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_OPACITY_LINE, AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX, AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH, AI_TABLE_FIELD_ITEM_MARGIN_RIGHT, AI_TABLE_FIELD_MAX_WIDTH, AI_TABLE_FIELD_MIDDLE_WIDTH, AI_TABLE_FIELD_MINI_WIDTH, AI_TABLE_FIELD_MIN_WIDTH, AI_TABLE_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, 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, extractLinkUrl, extractText, generateNewName, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getDefaultFieldValue, getDefaultI18nTextByKey, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getFieldOptions, getFieldValue, getHoverCell, getHoverEditorBoxOffset, getHoverEditorSpace, getI18nTextByKey, 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 };
9579
9729
  //# sourceMappingURL=ai-table-grid.mjs.map