@ai-table/grid 0.1.9 → 0.1.10

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 (72) hide show
  1. package/components/cell-editors/link/edit-link/edit-link.component.d.ts +0 -2
  2. package/components/cell-editors/link/edit-link/edit-link.component.d.ts.map +1 -1
  3. package/components/cell-editors/link/link-editor.component.d.ts.map +1 -1
  4. package/components/cell-editors/text/text-editor.component.d.ts +3 -1
  5. package/components/cell-editors/text/text-editor.component.d.ts.map +1 -1
  6. package/components/drag/drag.component.d.ts +11 -1
  7. package/components/drag/drag.component.d.ts.map +1 -1
  8. package/components/field-setting/field-setting.component.d.ts +6 -1
  9. package/components/field-setting/field-setting.component.d.ts.map +1 -1
  10. package/constants/table.d.ts +5 -0
  11. package/constants/table.d.ts.map +1 -1
  12. package/core/constants/field.d.ts +2 -0
  13. package/core/constants/field.d.ts.map +1 -1
  14. package/core/context.d.ts +3 -1
  15. package/core/context.d.ts.map +1 -1
  16. package/core/types/ai-table.d.ts +2 -1
  17. package/core/types/ai-table.d.ts.map +1 -1
  18. package/core/types/core.d.ts +0 -2
  19. package/core/types/core.d.ts.map +1 -1
  20. package/core/utils/common.d.ts.map +1 -1
  21. package/fesm2022/ai-table-grid.mjs +855 -304
  22. package/fesm2022/ai-table-grid.mjs.map +1 -1
  23. package/grid.component.d.ts +14 -7
  24. package/grid.component.d.ts.map +1 -1
  25. package/package.json +1 -1
  26. package/renderer/components/cells/attachment.component.d.ts +4 -5
  27. package/renderer/components/cells/attachment.component.d.ts.map +1 -1
  28. package/renderer/components/cells/cells.d.ts +1 -1
  29. package/renderer/components/cells/cells.d.ts.map +1 -1
  30. package/renderer/components/cells/hover-cell.d.ts +12 -0
  31. package/renderer/components/cells/hover-cell.d.ts.map +1 -0
  32. package/renderer/components/cells/link.component.d.ts +4 -5
  33. package/renderer/components/cells/link.component.d.ts.map +1 -1
  34. package/renderer/components/cells/progress.component.d.ts +3 -5
  35. package/renderer/components/cells/progress.component.d.ts.map +1 -1
  36. package/renderer/components/cells/rate.component.d.ts +3 -5
  37. package/renderer/components/cells/rate.component.d.ts.map +1 -1
  38. package/renderer/components/cells/rich-text.component.d.ts +4 -5
  39. package/renderer/components/cells/rich-text.component.d.ts.map +1 -1
  40. package/renderer/components/hover-cell.component.d.ts +5 -2
  41. package/renderer/components/hover-cell.component.d.ts.map +1 -1
  42. package/renderer/components/index.d.ts +1 -0
  43. package/renderer/components/index.d.ts.map +1 -1
  44. package/renderer/creations/create-active-cell-border.d.ts.map +1 -1
  45. package/renderer/creations/create-cells.d.ts.map +1 -1
  46. package/renderer/index.d.ts +0 -1
  47. package/renderer/index.d.ts.map +1 -1
  48. package/renderer/renderer.component.d.ts +4 -1
  49. package/renderer/renderer.component.d.ts.map +1 -1
  50. package/services/event.service.d.ts.map +1 -1
  51. package/services/scroll-controller.service.d.ts +75 -0
  52. package/services/scroll-controller.service.d.ts.map +1 -0
  53. package/services/selection.service.d.ts +3 -5
  54. package/services/selection.service.d.ts.map +1 -1
  55. package/types/component-config.d.ts +1 -0
  56. package/types/component-config.d.ts.map +1 -1
  57. package/types/grid.d.ts +5 -1
  58. package/types/grid.d.ts.map +1 -1
  59. package/utils/common.d.ts +1 -0
  60. package/utils/common.d.ts.map +1 -1
  61. package/utils/hover-cell.d.ts +1 -0
  62. package/utils/hover-cell.d.ts.map +1 -1
  63. package/utils/i18n.d.ts +4 -1
  64. package/utils/i18n.d.ts.map +1 -1
  65. package/utils/index.d.ts +1 -0
  66. package/utils/index.d.ts.map +1 -1
  67. package/utils/transform.d.ts +13 -0
  68. package/utils/transform.d.ts.map +1 -0
  69. package/renderer/interfaces/hover-cell.d.ts +0 -8
  70. package/renderer/interfaces/hover-cell.d.ts.map +0 -1
  71. package/renderer/interfaces/index.d.ts +0 -2
  72. package/renderer/interfaces/index.d.ts.map +0 -1
@@ -25,11 +25,11 @@ import { Transformer } from 'konva/lib/shapes/Transformer';
25
25
  import { Wedge } from 'konva/lib/shapes/Wedge';
26
26
  import * as i1$1 from 'ngx-tethys/popover';
27
27
  import { ThyPopoverRef, ThyPopover, ThyPopoverModule } from 'ngx-tethys/popover';
28
- import { AITableFieldType, AITableRowColumnType, isUndefinedOrNull, AITableSelectOptionStyle, DragType, isEmpty, AITableFilterOperation, AttachmentFieldBase, DateFieldBase, isDateValid, SelectFieldBase, LinkFieldBase, MemberFieldBase, NumberFieldBase, ProgressFieldBase, RateFieldBase, RichTextFieldBase, TextFieldBase, FieldModelBaseMap } from '@ai-table/utils';
28
+ import { AITableFieldGroup, AITableFieldType, AITableRowColumnType, DragType, isUndefinedOrNull, isUrl, AITableSelectOptionStyle, isEmpty, AITableFilterOperation, AttachmentFieldBase, DateFieldBase, isDateValid, SelectFieldBase, LinkFieldBase, MemberFieldBase, NumberFieldBase, ProgressFieldBase, RateFieldBase, RichTextFieldBase, TextFieldBase, FieldModelBaseMap } from '@ai-table/utils';
29
29
  import ObjectID from 'bson-objectid';
30
30
  import { customAlphabet } from 'nanoid';
31
31
  import * as _ from 'lodash';
32
- import { isNumber, includes, values, isString } from 'lodash';
32
+ import { isNumber, includes, values, isString, isObject } from 'lodash';
33
33
  import * as i1 from '@angular/forms';
34
34
  import { FormsModule } from '@angular/forms';
35
35
  import { ThyDatePicker, ThyDatePickerFormatPipe } from 'ngx-tethys/date-picker';
@@ -53,9 +53,9 @@ import { ThySelect, ThySelectModule } from 'ngx-tethys/select';
53
53
  import { ThyDot } from 'ngx-tethys/dot';
54
54
  import { ThyIcon } from 'ngx-tethys/icon';
55
55
  import { ThyTag } from 'ngx-tethys/tag';
56
- import { ThyDropdownMenuComponent, ThyDropdownDirective, ThyDropdownMenuItemDirective, ThyDropdownMenuItemIconDirective, ThyDropdownMenuItemNameDirective, ThyDropdownMenuItemExtendIconDirective, ThyDropdownAbstractMenu, ThyDropdownMenuItemMetaDirective } from 'ngx-tethys/dropdown';
56
+ import { ThyDropdownMenuComponent, ThyDropdownMenuGroup, ThyDropdownDirective, ThyDropdownMenuItemDirective, ThyDropdownMenuItemIconDirective, ThyDropdownMenuItemNameDirective, ThyDropdownMenuItemExtendIconDirective, ThyDropdownAbstractMenu, ThyDropdownMenuItemMetaDirective } from 'ngx-tethys/dropdown';
57
57
  import { ThySwitch } from 'ngx-tethys/switch';
58
- import { of, Subject, fromEvent, debounceTime, mergeWith, filter } from 'rxjs';
58
+ import { of, Subject, fromEvent, debounceTime, mergeWith, animationFrames, filter } from 'rxjs';
59
59
  import { ThyDivider } from 'ngx-tethys/divider';
60
60
  import * as i4 from 'ngx-tethys/avatar';
61
61
  import { ThyAvatarModule } from 'ngx-tethys/avatar';
@@ -67,8 +67,10 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
67
67
  import { fromUnixTime, subDays } from 'date-fns';
68
68
  import { isArray, TinyDate, helpers } from 'ngx-tethys/util';
69
69
  import { DEFAULT_COLORS } from 'ngx-tethys/color-picker';
70
+ import { isKeyHotkey } from 'is-hotkey';
70
71
  import { LRUCache } from 'lru-cache';
71
72
  import GraphemeSplitter from 'grapheme-splitter';
73
+ import { takeWhile, map } from 'rxjs/operators';
72
74
 
73
75
  const KO_CONTAINER_TOKEN = new InjectionToken('KO_CONTAINER_TOKEN');
74
76
 
@@ -529,6 +531,9 @@ var AITableGridI18nKey;
529
531
  AITableGridI18nKey["fieldTypeCreatedAt"] = "fieldTypeCreatedAt";
530
532
  AITableGridI18nKey["fieldTypeUpdatedBy"] = "fieldTypeUpdatedBy";
531
533
  AITableGridI18nKey["fieldTypeUpdatedAt"] = "fieldTypeUpdatedAt";
534
+ AITableGridI18nKey["fieldGroupBase"] = "fieldGroupBase";
535
+ AITableGridI18nKey["fieldGroupAdvanced"] = "fieldGroupAdvanced";
536
+ AITableGridI18nKey["rowAddFilterTooltip"] = "rowAddFilterTooltip";
532
537
  })(AITableGridI18nKey || (AITableGridI18nKey = {}));
533
538
  const AITableI18nText = {
534
539
  [AITableGridI18nKey.dataPickerPlaceholder]: '选择日期',
@@ -566,7 +571,10 @@ const AITableI18nText = {
566
571
  [AITableGridI18nKey.fieldTypeCreatedBy]: '创建人',
567
572
  [AITableGridI18nKey.fieldTypeCreatedAt]: '创建时间',
568
573
  [AITableGridI18nKey.fieldTypeUpdatedBy]: '更新人',
569
- [AITableGridI18nKey.fieldTypeUpdatedAt]: '更新时间'
574
+ [AITableGridI18nKey.fieldTypeUpdatedAt]: '更新时间',
575
+ [AITableGridI18nKey.fieldGroupBase]: '基础',
576
+ [AITableGridI18nKey.fieldGroupAdvanced]: '高级',
577
+ [AITableGridI18nKey.rowAddFilterTooltip]: '本记录已被筛选过滤,点击该记录以外位置将被隐藏'
570
578
  };
571
579
  const getDefaultI18nTextByKey = (key) => {
572
580
  return AITableI18nText[key] || key;
@@ -586,112 +594,124 @@ const AI_TABLE_FIELD_MINI_WIDTH = 140;
586
594
  const AI_TABLE_FIELD_MIN_WIDTH = 160;
587
595
  const AI_TABLE_FIELD_MIDDLE_WIDTH = 200;
588
596
  const AI_TABLE_FIELD_MAX_WIDTH = 300;
589
- function getFieldOptions(aiTable) {
590
- const defaultFieldOptions = [
591
- {
592
- type: AITableFieldType.text,
593
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeText),
594
- icon: 'font',
595
- width: AI_TABLE_FIELD_MAX_WIDTH
596
- },
597
- {
598
- type: AITableFieldType.richText,
599
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeRichText),
600
- icon: 'multiline-text',
601
- width: AI_TABLE_FIELD_MAX_WIDTH
602
- },
603
- {
604
- type: AITableFieldType.select,
605
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeSelect),
606
- icon: 'check-circle',
607
- width: AI_TABLE_FIELD_MIN_WIDTH
608
- },
609
- {
610
- type: AITableFieldType.select,
611
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeMultiSelect),
612
- icon: 'list-check',
613
- width: AI_TABLE_FIELD_MIDDLE_WIDTH,
614
- settings: {
615
- is_multiple: true
616
- }
617
- },
618
- {
619
- type: AITableFieldType.number,
620
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeNumber),
621
- icon: 'hashtag',
622
- width: AI_TABLE_FIELD_MINI_WIDTH
623
- },
624
- {
625
- type: AITableFieldType.date,
626
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeDate),
627
- icon: 'calendar',
628
- width: AI_TABLE_FIELD_MIDDLE_WIDTH
629
- },
630
- {
631
- type: AITableFieldType.member,
632
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeMember),
633
- icon: 'user',
634
- width: AI_TABLE_FIELD_MIN_WIDTH,
635
- settings: {
636
- is_multiple: false
637
- }
638
- },
639
- {
640
- type: AITableFieldType.progress,
641
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeProgress),
642
- icon: 'progress',
643
- width: AI_TABLE_FIELD_MIDDLE_WIDTH
644
- },
645
- {
646
- type: AITableFieldType.rate,
647
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeRate),
648
- icon: 'star-circle',
649
- width: AI_TABLE_FIELD_MIN_WIDTH
650
- },
651
- {
652
- type: AITableFieldType.link,
653
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeLink),
654
- icon: 'link-insert',
655
- width: AI_TABLE_FIELD_MIDDLE_WIDTH
656
- },
657
- {
658
- type: AITableFieldType.attachment,
659
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeAttachment),
660
- icon: 'attachment',
661
- width: AI_TABLE_FIELD_MIDDLE_WIDTH
662
- },
663
- {
664
- type: AITableFieldType.createdBy,
665
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeCreatedBy),
666
- icon: 'user',
667
- width: AI_TABLE_FIELD_MIN_WIDTH
668
- },
669
- {
670
- type: AITableFieldType.createdAt,
671
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeCreatedAt),
672
- icon: 'calendar',
673
- width: AI_TABLE_FIELD_MIDDLE_WIDTH
597
+ const defaultFieldOptions = [
598
+ {
599
+ type: AITableFieldType.text,
600
+ name: AITableGridI18nKey.fieldTypeText,
601
+ icon: 'font',
602
+ width: AI_TABLE_FIELD_MAX_WIDTH,
603
+ group: AITableFieldGroup.base
604
+ },
605
+ {
606
+ type: AITableFieldType.richText,
607
+ name: AITableGridI18nKey.fieldTypeRichText,
608
+ icon: 'multiline-text',
609
+ width: AI_TABLE_FIELD_MAX_WIDTH,
610
+ group: AITableFieldGroup.base
611
+ },
612
+ {
613
+ type: AITableFieldType.select,
614
+ name: AITableGridI18nKey.fieldTypeSelect,
615
+ icon: 'check-circle',
616
+ width: AI_TABLE_FIELD_MIN_WIDTH,
617
+ group: AITableFieldGroup.base
618
+ },
619
+ {
620
+ type: AITableFieldType.select,
621
+ name: AITableGridI18nKey.fieldTypeMultiSelect,
622
+ icon: 'list-check',
623
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH,
624
+ settings: {
625
+ is_multiple: true
674
626
  },
675
- {
676
- type: AITableFieldType.updatedBy,
677
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeUpdatedBy),
678
- icon: 'user',
679
- width: AI_TABLE_FIELD_MIN_WIDTH
627
+ group: AITableFieldGroup.base
628
+ },
629
+ {
630
+ type: AITableFieldType.number,
631
+ name: AITableGridI18nKey.fieldTypeNumber,
632
+ icon: 'hashtag',
633
+ width: AI_TABLE_FIELD_MINI_WIDTH,
634
+ group: AITableFieldGroup.base
635
+ },
636
+ {
637
+ type: AITableFieldType.date,
638
+ name: AITableGridI18nKey.fieldTypeDate,
639
+ icon: 'calendar',
640
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH,
641
+ group: AITableFieldGroup.base
642
+ },
643
+ {
644
+ type: AITableFieldType.member,
645
+ name: AITableGridI18nKey.fieldTypeMember,
646
+ icon: 'user',
647
+ width: AI_TABLE_FIELD_MIN_WIDTH,
648
+ settings: {
649
+ is_multiple: false
680
650
  },
681
- {
682
- type: AITableFieldType.updatedAt,
683
- name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeUpdatedAt),
684
- icon: 'calendar',
685
- width: AI_TABLE_FIELD_MIDDLE_WIDTH
686
- }
687
- ];
688
- const fieldOptions = [];
689
- Object.entries(aiTable.context?.aiFieldConfig()?.customFields || {}).forEach(([fieldType, fieldConfig]) => {
690
- if (fieldConfig?.fieldOption) {
691
- fieldOptions.push(fieldConfig.fieldOption);
692
- }
693
- });
694
- return [...defaultFieldOptions, ...fieldOptions];
651
+ group: AITableFieldGroup.base
652
+ },
653
+ {
654
+ type: AITableFieldType.progress,
655
+ name: AITableGridI18nKey.fieldTypeProgress,
656
+ icon: 'progress',
657
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH,
658
+ group: AITableFieldGroup.base
659
+ },
660
+ {
661
+ type: AITableFieldType.rate,
662
+ name: AITableGridI18nKey.fieldTypeRate,
663
+ icon: 'star-circle',
664
+ width: AI_TABLE_FIELD_MIN_WIDTH,
665
+ group: AITableFieldGroup.base
666
+ },
667
+ {
668
+ type: AITableFieldType.link,
669
+ name: AITableGridI18nKey.fieldTypeLink,
670
+ icon: 'link-insert',
671
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH,
672
+ group: AITableFieldGroup.base
673
+ },
674
+ {
675
+ type: AITableFieldType.attachment,
676
+ name: AITableGridI18nKey.fieldTypeAttachment,
677
+ icon: 'attachment',
678
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH,
679
+ group: AITableFieldGroup.base
680
+ },
681
+ {
682
+ type: AITableFieldType.createdBy,
683
+ name: AITableGridI18nKey.fieldTypeCreatedBy,
684
+ icon: 'user',
685
+ width: AI_TABLE_FIELD_MIN_WIDTH,
686
+ group: AITableFieldGroup.advanced
687
+ },
688
+ {
689
+ type: AITableFieldType.createdAt,
690
+ name: AITableGridI18nKey.fieldTypeCreatedAt,
691
+ icon: 'calendar',
692
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH,
693
+ group: AITableFieldGroup.advanced
694
+ },
695
+ {
696
+ type: AITableFieldType.updatedBy,
697
+ name: AITableGridI18nKey.fieldTypeUpdatedBy,
698
+ icon: 'user',
699
+ width: AI_TABLE_FIELD_MIN_WIDTH,
700
+ group: AITableFieldGroup.advanced
701
+ },
702
+ {
703
+ type: AITableFieldType.updatedAt,
704
+ name: AITableGridI18nKey.fieldTypeUpdatedAt,
705
+ icon: 'calendar',
706
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH,
707
+ group: AITableFieldGroup.advanced
708
+ }
709
+ ];
710
+ function getFieldOptions(aiTable) {
711
+ return aiTable.context?.fieldOptions();
712
+ }
713
+ function getFieldOptionMap(aiTable) {
714
+ return aiTable.context?.fieldOptionMap();
695
715
  }
696
716
 
697
717
  /**
@@ -987,6 +1007,9 @@ const AITable = {
987
1007
  return true;
988
1008
  }
989
1009
  return false;
1010
+ },
1011
+ getDragState(aiTable) {
1012
+ return aiTable.dragState?.()?.type || DragType.none;
990
1013
  }
991
1014
  };
992
1015
 
@@ -1127,6 +1150,7 @@ function createAITable(records, fields, gridData) {
1127
1150
  selectedFields: new Set(),
1128
1151
  selectedCells: new Set(),
1129
1152
  activeCell: null,
1153
+ expandCell: null,
1130
1154
  selectAllState: AITableSelectAllState.none
1131
1155
  }),
1132
1156
  keywordsMatchedCells: signal(new Set()),
@@ -1143,7 +1167,11 @@ function createAITable(records, fields, gridData) {
1143
1167
  }, {});
1144
1168
  }),
1145
1169
  recordsWillHidden: signal([]),
1146
- recordsWillMove: signal([])
1170
+ recordsWillMove: signal([]),
1171
+ dragState: signal({
1172
+ type: DragType.none,
1173
+ sourceIds: new Set()
1174
+ })
1147
1175
  };
1148
1176
  return aiTable;
1149
1177
  }
@@ -1299,7 +1327,7 @@ const AITableQueries = {
1299
1327
 
1300
1328
  class RendererContext {
1301
1329
  constructor(options) {
1302
- const { rowHeadWidth, linearRows, pointPosition, scrollState, visibleColumnsIndexMap, visibleRowsIndexMap, frozenColumnCount, references, aiFieldConfig, scrollAction, maxFields, maxRecords } = options;
1330
+ const { rowHeadWidth, linearRows, pointPosition, scrollState, visibleColumnsIndexMap, visibleRowsIndexMap, frozenColumnCount, references, aiFieldConfig, scrollAction, maxFields, maxRecords, fieldOptions, fieldOptionMap } = options;
1303
1331
  this.rowHeadWidth = rowHeadWidth;
1304
1332
  this.linearRows = linearRows;
1305
1333
  this.pointPosition = pointPosition;
@@ -1312,6 +1340,8 @@ class RendererContext {
1312
1340
  this.aiFieldConfig = aiFieldConfig;
1313
1341
  this.maxFields = maxFields;
1314
1342
  this.maxRecords = maxRecords;
1343
+ this.fieldOptions = fieldOptions;
1344
+ this.fieldOptionMap = fieldOptionMap;
1315
1345
  }
1316
1346
  setPointPosition(position) {
1317
1347
  const oldPosition = this.pointPosition();
@@ -1456,7 +1486,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
1456
1486
  }]
1457
1487
  }] });
1458
1488
 
1459
- const LINK_URL_REGEX = /^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/;
1460
1489
  /**
1461
1490
  * @private
1462
1491
  */
@@ -1467,7 +1496,6 @@ class LinkEditComponent {
1467
1496
  this.text = '';
1468
1497
  this.aiTable = input();
1469
1498
  this.confirm = new EventEmitter();
1470
- this.URLRegex = LINK_URL_REGEX;
1471
1499
  this.i18nTexts = computed(() => {
1472
1500
  return {
1473
1501
  linkText: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.linkText),
@@ -1497,6 +1525,10 @@ class LinkEditComponent {
1497
1525
  form.validator.setElementErrorMessage('url', getI18nTextByKey(this.aiTable(), AITableGridI18nKey.linkRequired));
1498
1526
  return;
1499
1527
  }
1528
+ if (this.url && !isUrl(this.url)) {
1529
+ form.validator.setElementErrorMessage('url', getI18nTextByKey(this.aiTable(), AITableGridI18nKey.invalidLinkFormat));
1530
+ return;
1531
+ }
1500
1532
  this.close();
1501
1533
  const text = this.text.trim();
1502
1534
  const url = this.url.trim();
@@ -1504,11 +1536,11 @@ class LinkEditComponent {
1504
1536
  this.confirm.emit(link);
1505
1537
  }
1506
1538
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LinkEditComponent, deps: [{ token: i1$1.ThyPopoverRef }], target: i0.ɵɵFactoryTarget.Component }); }
1507
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.10", type: LinkEditComponent, isStandalone: true, selector: "link-edit", inputs: { url: { classPropertyName: "url", publicName: "url", isSignal: false, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: false, isRequired: false, transformFunction: null }, aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirm: "confirm" }, ngImport: i0, template: "<form\n thyLayout=\"vertical\"\n thyStopPropagation\n thyForm\n #linkForm=\"thyForm\"\n [thyFormValidatorConfig]=\"validatorConfig()\"\n name=\"linkForm\"\n class=\"p-5\"\n>\n <thy-form-group [thyLabelText]=\"i18nTexts().linkText\">\n <input thyInput [placeholder]=\"i18nTexts().textPlaceholder\" name=\"text\" [(ngModel)]=\"text\" />\n </thy-form-group>\n <thy-form-group [thyLabelText]=\"i18nTexts().urlLabel\">\n <input name=\"url\" thyInput [placeholder]=\"i18nTexts().urlPlaceholder\" [pattern]=\"URLRegex\" type=\"text\" [(ngModel)]=\"url\" />\n </thy-form-group>\n <thy-form-group-footer thyAlign=\"right\">\n <div class=\"btn-pair\">\n <button thyStopPropagation thyButton=\"link-secondary\" thySize=\"sm\" (click)=\"close()\">{{ i18nTexts().cancel }}</button>\n <button thyStopPropagation thyButton=\"primary\" thySize=\"sm\" (thyFormSubmit)=\"apply(linkForm)\">{{ i18nTexts().apply }}</button>\n </div>\n </thy-form-group-footer>\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "directive", type: ThyInputDirective, selector: "input[thyInput], select[thyInput], textarea[thyInput]", inputs: ["thySize"], exportAs: ["thyInput"] }, { kind: "component", type: ThyButton, selector: "thy-button,[thy-button],[thyButton]", inputs: ["thyButton", "thyType", "thyLoading", "thyLoadingText", "thySize", "thyIcon", "thyBlock"] }, { kind: "directive", type: ThyFormSubmitDirective, selector: "[thyFormSubmit],[thy-form-submit]", outputs: ["thyFormSubmit"] }, { kind: "ngmodule", type: ThyFormModule }, { kind: "directive", type: i2.ThyFormDirective, selector: "[thyForm],[thy-form]", inputs: ["thyLayout", "thyEnterKeyMode", "thyFormValidatorConfig"], exportAs: ["thyForm"] }, { kind: "component", type: i2.ThyFormGroup, selector: "thy-form-group", inputs: ["thyLabelText", "thyLabelTextTranslateKey", "thyLabelRequired", "thyLabelPaddingTopClear", "thyFeedbackIcon", "thyTipsMode", "thyTips", "thyTipsTranslateKey", "thyRowFill"] }, { kind: "component", type: i2.ThyFormGroupFooter, selector: "thy-form-group-footer", inputs: ["thyAlign"] }] }); }
1539
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.10", type: LinkEditComponent, isStandalone: true, selector: "link-edit", inputs: { url: { classPropertyName: "url", publicName: "url", isSignal: false, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: false, isRequired: false, transformFunction: null }, aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirm: "confirm" }, ngImport: i0, template: "<form\n thyLayout=\"vertical\"\n thyStopPropagation\n thyForm\n #linkForm=\"thyForm\"\n [thyFormValidatorConfig]=\"validatorConfig()\"\n name=\"linkForm\"\n class=\"p-5\"\n>\n <thy-form-group [thyLabelText]=\"i18nTexts().linkText\">\n <input thyInput [placeholder]=\"i18nTexts().textPlaceholder\" name=\"text\" [(ngModel)]=\"text\" />\n </thy-form-group>\n <thy-form-group [thyLabelText]=\"i18nTexts().urlLabel\">\n <input name=\"url\" thyInput [placeholder]=\"i18nTexts().urlPlaceholder\" type=\"text\" [(ngModel)]=\"url\" />\n </thy-form-group>\n <thy-form-group-footer thyAlign=\"right\">\n <div class=\"btn-pair\">\n <button thyStopPropagation thyButton=\"link-secondary\" thySize=\"sm\" (click)=\"close()\">{{ i18nTexts().cancel }}</button>\n <button thyStopPropagation thyButton=\"primary\" thySize=\"sm\" (thyFormSubmit)=\"apply(linkForm)\">{{ i18nTexts().apply }}</button>\n </div>\n </thy-form-group-footer>\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "directive", type: ThyInputDirective, selector: "input[thyInput], select[thyInput], textarea[thyInput]", inputs: ["thySize"], exportAs: ["thyInput"] }, { kind: "component", type: ThyButton, selector: "thy-button,[thy-button],[thyButton]", inputs: ["thyButton", "thyType", "thyLoading", "thyLoadingText", "thySize", "thyIcon", "thyBlock"] }, { kind: "directive", type: ThyFormSubmitDirective, selector: "[thyFormSubmit],[thy-form-submit]", outputs: ["thyFormSubmit"] }, { kind: "ngmodule", type: ThyFormModule }, { kind: "directive", type: i2.ThyFormDirective, selector: "[thyForm],[thy-form]", inputs: ["thyLayout", "thyEnterKeyMode", "thyFormValidatorConfig"], exportAs: ["thyForm"] }, { kind: "component", type: i2.ThyFormGroup, selector: "thy-form-group", inputs: ["thyLabelText", "thyLabelTextTranslateKey", "thyLabelRequired", "thyLabelPaddingTopClear", "thyFeedbackIcon", "thyTipsMode", "thyTips", "thyTipsTranslateKey", "thyRowFill"] }, { kind: "component", type: i2.ThyFormGroupFooter, selector: "thy-form-group-footer", inputs: ["thyAlign"] }] }); }
1508
1540
  }
1509
1541
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LinkEditComponent, decorators: [{
1510
1542
  type: Component,
1511
- args: [{ selector: 'link-edit', imports: [FormsModule, ThyStopPropagationDirective, ThyInputDirective, ThyButton, ThyFormSubmitDirective, ThyFormModule], template: "<form\n thyLayout=\"vertical\"\n thyStopPropagation\n thyForm\n #linkForm=\"thyForm\"\n [thyFormValidatorConfig]=\"validatorConfig()\"\n name=\"linkForm\"\n class=\"p-5\"\n>\n <thy-form-group [thyLabelText]=\"i18nTexts().linkText\">\n <input thyInput [placeholder]=\"i18nTexts().textPlaceholder\" name=\"text\" [(ngModel)]=\"text\" />\n </thy-form-group>\n <thy-form-group [thyLabelText]=\"i18nTexts().urlLabel\">\n <input name=\"url\" thyInput [placeholder]=\"i18nTexts().urlPlaceholder\" [pattern]=\"URLRegex\" type=\"text\" [(ngModel)]=\"url\" />\n </thy-form-group>\n <thy-form-group-footer thyAlign=\"right\">\n <div class=\"btn-pair\">\n <button thyStopPropagation thyButton=\"link-secondary\" thySize=\"sm\" (click)=\"close()\">{{ i18nTexts().cancel }}</button>\n <button thyStopPropagation thyButton=\"primary\" thySize=\"sm\" (thyFormSubmit)=\"apply(linkForm)\">{{ i18nTexts().apply }}</button>\n </div>\n </thy-form-group-footer>\n</form>\n" }]
1543
+ args: [{ selector: 'link-edit', imports: [FormsModule, ThyStopPropagationDirective, ThyInputDirective, ThyButton, ThyFormSubmitDirective, ThyFormModule], template: "<form\n thyLayout=\"vertical\"\n thyStopPropagation\n thyForm\n #linkForm=\"thyForm\"\n [thyFormValidatorConfig]=\"validatorConfig()\"\n name=\"linkForm\"\n class=\"p-5\"\n>\n <thy-form-group [thyLabelText]=\"i18nTexts().linkText\">\n <input thyInput [placeholder]=\"i18nTexts().textPlaceholder\" name=\"text\" [(ngModel)]=\"text\" />\n </thy-form-group>\n <thy-form-group [thyLabelText]=\"i18nTexts().urlLabel\">\n <input name=\"url\" thyInput [placeholder]=\"i18nTexts().urlPlaceholder\" type=\"text\" [(ngModel)]=\"url\" />\n </thy-form-group>\n <thy-form-group-footer thyAlign=\"right\">\n <div class=\"btn-pair\">\n <button thyStopPropagation thyButton=\"link-secondary\" thySize=\"sm\" (click)=\"close()\">{{ i18nTexts().cancel }}</button>\n <button thyStopPropagation thyButton=\"primary\" thySize=\"sm\" (thyFormSubmit)=\"apply(linkForm)\">{{ i18nTexts().apply }}</button>\n </div>\n </thy-form-group-footer>\n</form>\n" }]
1512
1544
  }], ctorParameters: () => [{ type: i1$1.ThyPopoverRef }], propDecorators: { url: [{
1513
1545
  type: Input
1514
1546
  }], text: [{
@@ -1532,13 +1564,10 @@ class LinkCellEditorComponent extends AbstractEditCellEditor {
1532
1564
  });
1533
1565
  }
1534
1566
  isValidLink(link) {
1535
- if (!link?.text?.trim()) {
1567
+ if (!link.text) {
1536
1568
  return true;
1537
1569
  }
1538
- if (!link.url) {
1539
- return LINK_URL_REGEX.test(link.text);
1540
- }
1541
- return true;
1570
+ return isUrl(link.text);
1542
1571
  }
1543
1572
  createLinkValue(link) {
1544
1573
  const text = link?.text?.trim();
@@ -1564,11 +1593,12 @@ class LinkCellEditorComponent extends AbstractEditCellEditor {
1564
1593
  this.url = this.modelValue?.url ?? '';
1565
1594
  }
1566
1595
  updateValue() {
1567
- if (!this.isValidLink({ text: this.text, url: this.url ?? '' })) {
1596
+ const linkValue = this.createLinkValue({ text: this.text, url: this.url ?? '' });
1597
+ if (!this.isValidLink(linkValue)) {
1568
1598
  this.notifyService.error(getI18nTextByKey(this.aiTable, AITableGridI18nKey.invalidLinkFormat));
1569
1599
  return;
1570
1600
  }
1571
- this.modelValue = this.createLinkValue({ text: this.text, url: this.url ?? '' });
1601
+ this.modelValue = linkValue;
1572
1602
  if (!_.isEqual(this.originValue, this.modelValue)) {
1573
1603
  super.update();
1574
1604
  this.originValue = this.modelValue;
@@ -1741,11 +1771,13 @@ class TextCellEditorComponent extends AbstractEditCellEditor {
1741
1771
  this.render2 = inject(Renderer2);
1742
1772
  this.maxHeight = 148;
1743
1773
  this.minHeight = 24;
1774
+ this.isSelectAll = input(false);
1744
1775
  }
1745
1776
  ngAfterViewInit() {
1746
1777
  setTimeout(() => {
1747
1778
  this.updateStyle();
1748
- });
1779
+ this.handleSelectAll();
1780
+ }, 0);
1749
1781
  }
1750
1782
  updateStyle() {
1751
1783
  const textarea = this.elementRef.nativeElement.querySelector('textarea');
@@ -1758,6 +1790,12 @@ class TextCellEditorComponent extends AbstractEditCellEditor {
1758
1790
  this.render2.setStyle(textarea, 'resize', 'none');
1759
1791
  }
1760
1792
  }
1793
+ handleSelectAll() {
1794
+ if (this.isSelectAll()) {
1795
+ const textarea = this.elementRef.nativeElement.querySelector('textarea');
1796
+ textarea.select();
1797
+ }
1798
+ }
1761
1799
  valueChange() {
1762
1800
  this.updateStyle();
1763
1801
  }
@@ -1766,8 +1804,9 @@ class TextCellEditorComponent extends AbstractEditCellEditor {
1766
1804
  this.closePopover();
1767
1805
  }
1768
1806
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: TextCellEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1769
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.10", type: TextCellEditorComponent, isStandalone: true, selector: "text-cell-editor", host: { classAttribute: "text-cell-editor" }, usesInheritance: true, ngImport: i0, template: `
1807
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.10", type: TextCellEditorComponent, isStandalone: true, selector: "text-cell-editor", inputs: { isSelectAll: { classPropertyName: "isSelectAll", publicName: "isSelectAll", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "text-cell-editor" }, usesInheritance: true, ngImport: i0, template: `
1770
1808
  <textarea
1809
+ #textarea
1771
1810
  placeholder=""
1772
1811
  rows="1"
1773
1812
  thyInput
@@ -1785,6 +1824,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
1785
1824
  selector: 'text-cell-editor',
1786
1825
  template: `
1787
1826
  <textarea
1827
+ #textarea
1788
1828
  placeholder=""
1789
1829
  rows="1"
1790
1830
  thyInput
@@ -1926,7 +1966,8 @@ class AITableFieldSetting {
1926
1966
  };
1927
1967
  });
1928
1968
  this.fieldOptions = computed(() => {
1929
- return getFieldOptions(this.aiTable());
1969
+ const fieldOptions = getFieldOptions(this.aiTable());
1970
+ return _.groupBy(fieldOptions, 'group');
1930
1971
  });
1931
1972
  this.aITableFieldType = AITableFieldType;
1932
1973
  this.isMultipleMember = false;
@@ -1945,7 +1986,9 @@ class AITableFieldSetting {
1945
1986
  fieldType: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldType),
1946
1987
  allowMultipleMembers: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.allowMultipleMembers),
1947
1988
  cancel: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.cancel),
1948
- confirm: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.confirm)
1989
+ confirm: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.confirm),
1990
+ base: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldGroupBase),
1991
+ advanced: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldGroupAdvanced)
1949
1992
  };
1950
1993
  });
1951
1994
  }
@@ -1997,7 +2040,7 @@ class AITableFieldSetting {
1997
2040
  this.thyPopoverRef.close();
1998
2041
  }
1999
2042
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableFieldSetting, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2000
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableFieldSetting, isStandalone: true, selector: "ai-table-field-setting", inputs: { aiEditField: { classPropertyName: "aiEditField", publicName: "aiEditField", isSignal: true, isRequired: true, transformFunction: null }, aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: true, transformFunction: null }, aiExternalTemplate: { classPropertyName: "aiExternalTemplate", publicName: "aiExternalTemplate", isSignal: true, isRequired: false, transformFunction: null }, isUpdate: { classPropertyName: "isUpdate", publicName: "isUpdate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiEditField: "aiEditFieldChange", addField: "addField", setField: "setField" }, host: { classAttribute: "field-setting d-block pl-5 pr-5 pb-5 pt-4" }, ngImport: i0, template: "<form thyForm name=\"createPropertyForm\" [thyFormValidatorConfig]=\"validatorConfig()\" thyLayout=\"vertical\">\n <thy-form-group thyLabelRequired [thyLabelText]=\"i18nTexts().columnName\">\n <thy-input-group>\n <input\n thyInput\n [thyAutofocus]=\"true\"\n name=\"fieldName\"\n [maxlength]=\"fieldMaxLength\"\n [(ngModel)]=\"aiEditField().name\"\n (ngModelChange)=\"nameChange($event)\"\n required\n [placeholder]=\"i18nTexts().columnNamePlaceholder\"\n [thyUniqueCheck]=\"checkUniqueName\"\n />\n <ng-template #suffix>\n <thy-input-count></thy-input-count>\n </ng-template>\n </thy-input-group>\n </thy-form-group>\n <thy-form-group [thyLabelText]=\"i18nTexts().fieldType\">\n <div class=\"thy-dropdown-menu py-0\">\n <div class=\"ml-n5 mr-n5\">\n <span\n thyDropdownMenuItem\n [thyDropdown]=\"menu\"\n [thyDisabled]=\"isUpdate()\"\n thyTrigger=\"hover\"\n thyPlacement=\"right\"\n (click)=\"fieldTypeClick($event)\"\n >\n <thy-icon thyDropdownMenuItemIcon [thyIconName]=\"selectedFieldOption().icon\"></thy-icon>\n <span thyDropdownMenuItemName>{{ selectedFieldOption().name }}</span>\n <thy-icon thyDropdownMenuItemExtendIcon thyIconName=\"angle-right\" class=\"text-desc\"></thy-icon>\n </span>\n </div>\n </div>\n\n @if (selectedFieldOption().type === aITableFieldType.member) {\n <div class=\"d-flex justify-content-between mt-3\">\n {{ i18nTexts().allowMultipleMembers }}\n <thy-switch\n name=\"isMultipleMember\"\n [thyDisabled]=\"isUpdate()\"\n [(ngModel)]=\"isMultipleMember\"\n (ngModelChange)=\"multipleMemberChange()\"\n thySize=\"sm\"\n ></thy-switch>\n </div>\n }\n </thy-form-group>\n @if (aiExternalTemplate()) {\n <ng-container *ngTemplateOutlet=\"aiExternalTemplate()\"></ng-container>\n }\n <thy-form-group-footer thyAlign=\"right\">\n <button thyButton=\"link-secondary\" (click)=\"cancel()\" thySize=\"sm\">{{ i18nTexts().cancel }}</button>\n <button thyButton=\"primary\" (thyFormSubmit)=\"editFieldProperty()\" thySize=\"sm\">{{ i18nTexts().confirm }}</button>\n </thy-form-group-footer>\n</form>\n\n<thy-dropdown-menu #menu>\n @for (item of fieldOptions(); track $index) {\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{\n active: (item | fieldIsSameOption: aiEditField())\n }\"\n (click)=\"selectFieldType(item)\"\n >\n <thy-icon [thyIconName]=\"item.icon!\"></thy-icon>\n <span thyDropdownMenuItemName>{{ item.name }}</span>\n </a>\n }\n</thy-dropdown-menu>\n", styles: [":host{width:350px}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyInputGroup, selector: "thy-input-group", inputs: ["thyAppendText", "thyAppendTextTranslateKey", "thyPrependText", "thyPrependTextTranslateKey", "thySize"] }, { kind: "component", type: ThyInputCount, selector: "thy-input-count", inputs: ["thyInput"] }, { kind: "directive", type: ThyInputDirective, selector: "input[thyInput], select[thyInput], textarea[thyInput]", inputs: ["thySize"], exportAs: ["thyInput"] }, { kind: "directive", type: ThyUniqueCheckValidator, selector: "[thyUniqueCheck]", inputs: ["thyUniqueCheck"] }, { kind: "component", type: ThyDropdownMenuComponent, selector: "thy-dropdown-menu", inputs: ["thyWidth", "thyImmediateRender"] }, { kind: "directive", type: ThyDropdownDirective, selector: "[thyDropdown]", inputs: ["thyDropdownMenu", "thyDropdown", "thyTrigger", "thyShowDelay", "thyHideDelay", "thyActiveClass", "thyPopoverOptions", "thyPlacement", "thyMenuInsideClosable", "thyPanelClass"], outputs: ["thyActiveChange"] }, { kind: "directive", type: ThyDropdownMenuItemDirective, selector: "[thyDropdownMenuItem]", inputs: ["thyType", "thyDisabled"] }, { kind: "directive", type: ThyDropdownMenuItemIconDirective, selector: "[thyDropdownMenuItemIcon]" }, { kind: "directive", type: ThyDropdownMenuItemNameDirective, selector: "[thyDropdownMenuItemName]" }, { kind: "directive", type: ThyDropdownMenuItemExtendIconDirective, selector: "[thyDropdownMenuItemExtendIcon]" }, { kind: "component", type: ThyButton, selector: "thy-button,[thy-button],[thyButton]", inputs: ["thyButton", "thyType", "thyLoading", "thyLoadingText", "thySize", "thyIcon", "thyBlock"] }, { kind: "component", type: ThySwitch, selector: "thy-switch", inputs: ["thyType", "thySize", "thyDisabled", "thyLoading"], outputs: ["thyChange"] }, { kind: "ngmodule", type: ThyFormModule }, { kind: "directive", type: i2.ThyFormDirective, selector: "[thyForm],[thy-form]", inputs: ["thyLayout", "thyEnterKeyMode", "thyFormValidatorConfig"], exportAs: ["thyForm"] }, { kind: "component", type: i2.ThyFormGroup, selector: "thy-form-group", inputs: ["thyLabelText", "thyLabelTextTranslateKey", "thyLabelRequired", "thyLabelPaddingTopClear", "thyFeedbackIcon", "thyTipsMode", "thyTips", "thyTipsTranslateKey", "thyRowFill"] }, { kind: "directive", type: i2.ThyFormSubmitDirective, selector: "[thyFormSubmit],[thy-form-submit]", outputs: ["thyFormSubmit"] }, { kind: "component", type: i2.ThyFormGroupFooter, selector: "thy-form-group-footer", inputs: ["thyAlign"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ThyAutofocusDirective, selector: "input[thyAutofocus],textarea[thyAutofocus]", inputs: ["thyAutofocus", "thyAutoSelect"] }, { kind: "pipe", type: AITableFieldIsSameOptionPipe, name: "fieldIsSameOption" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2043
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableFieldSetting, isStandalone: true, selector: "ai-table-field-setting", inputs: { aiEditField: { classPropertyName: "aiEditField", publicName: "aiEditField", isSignal: true, isRequired: true, transformFunction: null }, aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: true, transformFunction: null }, aiExternalTemplate: { classPropertyName: "aiExternalTemplate", publicName: "aiExternalTemplate", isSignal: true, isRequired: false, transformFunction: null }, isUpdate: { classPropertyName: "isUpdate", publicName: "isUpdate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiEditField: "aiEditFieldChange", addField: "addField", setField: "setField" }, host: { classAttribute: "field-setting d-block pl-5 pr-5 pb-5 pt-4" }, ngImport: i0, template: "<form thyForm name=\"createPropertyForm\" [thyFormValidatorConfig]=\"validatorConfig()\" thyLayout=\"vertical\">\n <thy-form-group thyLabelRequired [thyLabelText]=\"i18nTexts().columnName\">\n <thy-input-group>\n <input\n thyInput\n [thyAutofocus]=\"true\"\n name=\"fieldName\"\n [maxlength]=\"fieldMaxLength\"\n [(ngModel)]=\"aiEditField().name\"\n (ngModelChange)=\"nameChange($event)\"\n required\n [placeholder]=\"i18nTexts().columnNamePlaceholder\"\n [thyUniqueCheck]=\"checkUniqueName\"\n />\n <ng-template #suffix>\n <thy-input-count></thy-input-count>\n </ng-template>\n </thy-input-group>\n </thy-form-group>\n <thy-form-group [thyLabelText]=\"i18nTexts().fieldType\">\n <div class=\"thy-dropdown-menu py-0\">\n <div class=\"ml-n5 mr-n5\">\n <span\n thyDropdownMenuItem\n [thyDropdown]=\"menu\"\n [thyDisabled]=\"isUpdate()\"\n thyTrigger=\"hover\"\n thyPlacement=\"right\"\n (click)=\"fieldTypeClick($event)\"\n >\n <thy-icon thyDropdownMenuItemIcon [thyIconName]=\"selectedFieldOption().icon\"></thy-icon>\n <span thyDropdownMenuItemName>{{ selectedFieldOption().name }}</span>\n <thy-icon thyDropdownMenuItemExtendIcon thyIconName=\"angle-right\" class=\"text-desc\"></thy-icon>\n </span>\n </div>\n </div>\n\n @if (selectedFieldOption().type === aITableFieldType.member) {\n <div class=\"d-flex justify-content-between mt-3\">\n {{ i18nTexts().allowMultipleMembers }}\n <thy-switch\n name=\"isMultipleMember\"\n [thyDisabled]=\"isUpdate()\"\n [(ngModel)]=\"isMultipleMember\"\n (ngModelChange)=\"multipleMemberChange()\"\n thySize=\"sm\"\n ></thy-switch>\n </div>\n }\n </thy-form-group>\n @if (aiExternalTemplate()) {\n <ng-container *ngTemplateOutlet=\"aiExternalTemplate()\"></ng-container>\n }\n <thy-form-group-footer thyAlign=\"right\">\n <button thyButton=\"link-secondary\" (click)=\"cancel()\" thySize=\"sm\">{{ i18nTexts().cancel }}</button>\n <button thyButton=\"primary\" (thyFormSubmit)=\"editFieldProperty()\" thySize=\"sm\">{{ i18nTexts().confirm }}</button>\n </thy-form-group-footer>\n</form>\n\n<thy-dropdown-menu #menu>\n <thy-dropdown-menu-group [thyTitle]=\"i18nTexts().base\">\n @for (item of fieldOptions().base; track $index) {\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{\n active: (item | fieldIsSameOption: aiEditField())\n }\"\n (click)=\"selectFieldType(item)\"\n >\n <thy-icon [thyIconName]=\"item.icon!\"></thy-icon>\n <span thyDropdownMenuItemName>{{ item.name }}</span>\n </a>\n }\n </thy-dropdown-menu-group>\n\n <thy-dropdown-menu-group [thyTitle]=\"i18nTexts().advanced\">\n @for (item of fieldOptions().advanced; track $index) {\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{\n active: (item | fieldIsSameOption: aiEditField())\n }\"\n (click)=\"selectFieldType(item)\"\n >\n <thy-icon [thyIconName]=\"item.icon!\"></thy-icon>\n <span thyDropdownMenuItemName>{{ item.name }}</span>\n </a>\n }\n </thy-dropdown-menu-group>\n</thy-dropdown-menu>\n", styles: [":host{width:350px}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyInputGroup, selector: "thy-input-group", inputs: ["thyAppendText", "thyAppendTextTranslateKey", "thyPrependText", "thyPrependTextTranslateKey", "thySize"] }, { kind: "component", type: ThyInputCount, selector: "thy-input-count", inputs: ["thyInput"] }, { kind: "directive", type: ThyInputDirective, selector: "input[thyInput], select[thyInput], textarea[thyInput]", inputs: ["thySize"], exportAs: ["thyInput"] }, { kind: "directive", type: ThyUniqueCheckValidator, selector: "[thyUniqueCheck]", inputs: ["thyUniqueCheck"] }, { kind: "component", type: ThyDropdownMenuComponent, selector: "thy-dropdown-menu", inputs: ["thyWidth", "thyImmediateRender"] }, { kind: "component", type: ThyDropdownMenuGroup, selector: "thy-dropdown-menu-group", inputs: ["thyTitle"] }, { kind: "directive", type: ThyDropdownDirective, selector: "[thyDropdown]", inputs: ["thyDropdownMenu", "thyDropdown", "thyTrigger", "thyShowDelay", "thyHideDelay", "thyActiveClass", "thyPopoverOptions", "thyPlacement", "thyMenuInsideClosable", "thyPanelClass"], outputs: ["thyActiveChange"] }, { kind: "directive", type: ThyDropdownMenuItemDirective, selector: "[thyDropdownMenuItem]", inputs: ["thyType", "thyDisabled"] }, { kind: "directive", type: ThyDropdownMenuItemIconDirective, selector: "[thyDropdownMenuItemIcon]" }, { kind: "directive", type: ThyDropdownMenuItemNameDirective, selector: "[thyDropdownMenuItemName]" }, { kind: "directive", type: ThyDropdownMenuItemExtendIconDirective, selector: "[thyDropdownMenuItemExtendIcon]" }, { kind: "component", type: ThyButton, selector: "thy-button,[thy-button],[thyButton]", inputs: ["thyButton", "thyType", "thyLoading", "thyLoadingText", "thySize", "thyIcon", "thyBlock"] }, { kind: "component", type: ThySwitch, selector: "thy-switch", inputs: ["thyType", "thySize", "thyDisabled", "thyLoading"], outputs: ["thyChange"] }, { kind: "ngmodule", type: ThyFormModule }, { kind: "directive", type: i2.ThyFormDirective, selector: "[thyForm],[thy-form]", inputs: ["thyLayout", "thyEnterKeyMode", "thyFormValidatorConfig"], exportAs: ["thyForm"] }, { kind: "component", type: i2.ThyFormGroup, selector: "thy-form-group", inputs: ["thyLabelText", "thyLabelTextTranslateKey", "thyLabelRequired", "thyLabelPaddingTopClear", "thyFeedbackIcon", "thyTipsMode", "thyTips", "thyTipsTranslateKey", "thyRowFill"] }, { kind: "directive", type: i2.ThyFormSubmitDirective, selector: "[thyFormSubmit],[thy-form-submit]", outputs: ["thyFormSubmit"] }, { kind: "component", type: i2.ThyFormGroupFooter, selector: "thy-form-group-footer", inputs: ["thyAlign"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ThyAutofocusDirective, selector: "input[thyAutofocus],textarea[thyAutofocus]", inputs: ["thyAutofocus", "thyAutoSelect"] }, { kind: "pipe", type: AITableFieldIsSameOptionPipe, name: "fieldIsSameOption" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2001
2044
  }
2002
2045
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableFieldSetting, decorators: [{
2003
2046
  type: Component,
@@ -2010,6 +2053,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
2010
2053
  ThyInputDirective,
2011
2054
  ThyUniqueCheckValidator,
2012
2055
  ThyDropdownMenuComponent,
2056
+ ThyDropdownMenuGroup,
2013
2057
  ThyDropdownDirective,
2014
2058
  ThyDropdownMenuItemDirective,
2015
2059
  ThyDropdownMenuItemIconDirective,
@@ -2023,7 +2067,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
2023
2067
  AITableFieldIsSameOptionPipe
2024
2068
  ], host: {
2025
2069
  class: 'field-setting d-block pl-5 pr-5 pb-5 pt-4'
2026
- }, template: "<form thyForm name=\"createPropertyForm\" [thyFormValidatorConfig]=\"validatorConfig()\" thyLayout=\"vertical\">\n <thy-form-group thyLabelRequired [thyLabelText]=\"i18nTexts().columnName\">\n <thy-input-group>\n <input\n thyInput\n [thyAutofocus]=\"true\"\n name=\"fieldName\"\n [maxlength]=\"fieldMaxLength\"\n [(ngModel)]=\"aiEditField().name\"\n (ngModelChange)=\"nameChange($event)\"\n required\n [placeholder]=\"i18nTexts().columnNamePlaceholder\"\n [thyUniqueCheck]=\"checkUniqueName\"\n />\n <ng-template #suffix>\n <thy-input-count></thy-input-count>\n </ng-template>\n </thy-input-group>\n </thy-form-group>\n <thy-form-group [thyLabelText]=\"i18nTexts().fieldType\">\n <div class=\"thy-dropdown-menu py-0\">\n <div class=\"ml-n5 mr-n5\">\n <span\n thyDropdownMenuItem\n [thyDropdown]=\"menu\"\n [thyDisabled]=\"isUpdate()\"\n thyTrigger=\"hover\"\n thyPlacement=\"right\"\n (click)=\"fieldTypeClick($event)\"\n >\n <thy-icon thyDropdownMenuItemIcon [thyIconName]=\"selectedFieldOption().icon\"></thy-icon>\n <span thyDropdownMenuItemName>{{ selectedFieldOption().name }}</span>\n <thy-icon thyDropdownMenuItemExtendIcon thyIconName=\"angle-right\" class=\"text-desc\"></thy-icon>\n </span>\n </div>\n </div>\n\n @if (selectedFieldOption().type === aITableFieldType.member) {\n <div class=\"d-flex justify-content-between mt-3\">\n {{ i18nTexts().allowMultipleMembers }}\n <thy-switch\n name=\"isMultipleMember\"\n [thyDisabled]=\"isUpdate()\"\n [(ngModel)]=\"isMultipleMember\"\n (ngModelChange)=\"multipleMemberChange()\"\n thySize=\"sm\"\n ></thy-switch>\n </div>\n }\n </thy-form-group>\n @if (aiExternalTemplate()) {\n <ng-container *ngTemplateOutlet=\"aiExternalTemplate()\"></ng-container>\n }\n <thy-form-group-footer thyAlign=\"right\">\n <button thyButton=\"link-secondary\" (click)=\"cancel()\" thySize=\"sm\">{{ i18nTexts().cancel }}</button>\n <button thyButton=\"primary\" (thyFormSubmit)=\"editFieldProperty()\" thySize=\"sm\">{{ i18nTexts().confirm }}</button>\n </thy-form-group-footer>\n</form>\n\n<thy-dropdown-menu #menu>\n @for (item of fieldOptions(); track $index) {\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{\n active: (item | fieldIsSameOption: aiEditField())\n }\"\n (click)=\"selectFieldType(item)\"\n >\n <thy-icon [thyIconName]=\"item.icon!\"></thy-icon>\n <span thyDropdownMenuItemName>{{ item.name }}</span>\n </a>\n }\n</thy-dropdown-menu>\n", styles: [":host{width:350px}\n"] }]
2070
+ }, template: "<form thyForm name=\"createPropertyForm\" [thyFormValidatorConfig]=\"validatorConfig()\" thyLayout=\"vertical\">\n <thy-form-group thyLabelRequired [thyLabelText]=\"i18nTexts().columnName\">\n <thy-input-group>\n <input\n thyInput\n [thyAutofocus]=\"true\"\n name=\"fieldName\"\n [maxlength]=\"fieldMaxLength\"\n [(ngModel)]=\"aiEditField().name\"\n (ngModelChange)=\"nameChange($event)\"\n required\n [placeholder]=\"i18nTexts().columnNamePlaceholder\"\n [thyUniqueCheck]=\"checkUniqueName\"\n />\n <ng-template #suffix>\n <thy-input-count></thy-input-count>\n </ng-template>\n </thy-input-group>\n </thy-form-group>\n <thy-form-group [thyLabelText]=\"i18nTexts().fieldType\">\n <div class=\"thy-dropdown-menu py-0\">\n <div class=\"ml-n5 mr-n5\">\n <span\n thyDropdownMenuItem\n [thyDropdown]=\"menu\"\n [thyDisabled]=\"isUpdate()\"\n thyTrigger=\"hover\"\n thyPlacement=\"right\"\n (click)=\"fieldTypeClick($event)\"\n >\n <thy-icon thyDropdownMenuItemIcon [thyIconName]=\"selectedFieldOption().icon\"></thy-icon>\n <span thyDropdownMenuItemName>{{ selectedFieldOption().name }}</span>\n <thy-icon thyDropdownMenuItemExtendIcon thyIconName=\"angle-right\" class=\"text-desc\"></thy-icon>\n </span>\n </div>\n </div>\n\n @if (selectedFieldOption().type === aITableFieldType.member) {\n <div class=\"d-flex justify-content-between mt-3\">\n {{ i18nTexts().allowMultipleMembers }}\n <thy-switch\n name=\"isMultipleMember\"\n [thyDisabled]=\"isUpdate()\"\n [(ngModel)]=\"isMultipleMember\"\n (ngModelChange)=\"multipleMemberChange()\"\n thySize=\"sm\"\n ></thy-switch>\n </div>\n }\n </thy-form-group>\n @if (aiExternalTemplate()) {\n <ng-container *ngTemplateOutlet=\"aiExternalTemplate()\"></ng-container>\n }\n <thy-form-group-footer thyAlign=\"right\">\n <button thyButton=\"link-secondary\" (click)=\"cancel()\" thySize=\"sm\">{{ i18nTexts().cancel }}</button>\n <button thyButton=\"primary\" (thyFormSubmit)=\"editFieldProperty()\" thySize=\"sm\">{{ i18nTexts().confirm }}</button>\n </thy-form-group-footer>\n</form>\n\n<thy-dropdown-menu #menu>\n <thy-dropdown-menu-group [thyTitle]=\"i18nTexts().base\">\n @for (item of fieldOptions().base; track $index) {\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{\n active: (item | fieldIsSameOption: aiEditField())\n }\"\n (click)=\"selectFieldType(item)\"\n >\n <thy-icon [thyIconName]=\"item.icon!\"></thy-icon>\n <span thyDropdownMenuItemName>{{ item.name }}</span>\n </a>\n }\n </thy-dropdown-menu-group>\n\n <thy-dropdown-menu-group [thyTitle]=\"i18nTexts().advanced\">\n @for (item of fieldOptions().advanced; track $index) {\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{\n active: (item | fieldIsSameOption: aiEditField())\n }\"\n (click)=\"selectFieldType(item)\"\n >\n <thy-icon [thyIconName]=\"item.icon!\"></thy-icon>\n <span thyDropdownMenuItemName>{{ item.name }}</span>\n </a>\n }\n </thy-dropdown-menu-group>\n</thy-dropdown-menu>\n", styles: [":host{width:350px}\n"] }]
2027
2071
  }] });
2028
2072
 
2029
2073
  class AITableGridSelectionService {
@@ -2039,10 +2083,6 @@ class AITableGridSelectionService {
2039
2083
  }
2040
2084
  initialize(aiTable) {
2041
2085
  this.aiTable = aiTable;
2042
- this.aiTable.dragState = signal({
2043
- type: DragType.none,
2044
- sourceIds: new Set()
2045
- });
2046
2086
  }
2047
2087
  clearSelection() {
2048
2088
  this.aiTable.selection.set({
@@ -2050,12 +2090,19 @@ class AITableGridSelectionService {
2050
2090
  selectedFields: new Set(),
2051
2091
  selectedCells: new Set(),
2052
2092
  activeCell: null,
2093
+ expandCell: null,
2053
2094
  selectAllState: AITableSelectAllState.none
2054
2095
  });
2055
2096
  }
2056
2097
  setActiveCell(activeCell) {
2057
2098
  this.aiTable.selection().activeCell = activeCell;
2058
2099
  }
2100
+ setExpandCell(expandCell) {
2101
+ this.aiTable.selection.set({
2102
+ ...this.aiTable.selection(),
2103
+ expandCell: expandCell
2104
+ });
2105
+ }
2059
2106
  selectField(fieldId) {
2060
2107
  if (this.aiTable.selection().selectedFields.has(fieldId)) {
2061
2108
  return;
@@ -2069,18 +2116,6 @@ class AITableGridSelectionService {
2069
2116
  get selectedRecords() {
2070
2117
  return this.aiTable.selection().selectedRecords;
2071
2118
  }
2072
- drag(config) {
2073
- this.aiTable.dragState.set(config);
2074
- }
2075
- getDragStateType() {
2076
- return this.aiTable.dragState?.()?.type;
2077
- }
2078
- clearDrag() {
2079
- this.aiTable.dragState.set({
2080
- type: DragType.none,
2081
- sourceIds: new Set()
2082
- });
2083
- }
2084
2119
  selectRecord(recordId) {
2085
2120
  if (this.aiTable.selection().selectedRecords.has(recordId)) {
2086
2121
  this.aiTable.selection().selectedRecords.delete(recordId);
@@ -2094,6 +2129,7 @@ class AITableGridSelectionService {
2094
2129
  selectedFields: new Set(),
2095
2130
  selectedCells: new Set(),
2096
2131
  activeCell: null,
2132
+ expandCell: null,
2097
2133
  selectAllState: this.selectAllState()
2098
2134
  });
2099
2135
  }
@@ -2305,6 +2341,11 @@ const AI_TABLE_PROGRESS_BAR_POINTER_WIDTH = 8;
2305
2341
  const AI_TABLE_PROGRESS_TEXT_WIDTH = 46;
2306
2342
  const AI_TABLE_POPOVER_LEFT_OFFSET = 4;
2307
2343
  const AI_TABLE_RATE_MAX = 5;
2344
+ const AI_TABLE_SCROLL_BAR_SIZE = 18;
2345
+ const AI_TABLE_AUTO_SCROLL_LEFT_THRESHOLD = 40;
2346
+ const AI_TABLE_AUTO_SCROLL_RIGHT_THRESHOLD = 40;
2347
+ const AI_TABLE_AUTO_SCROLL_TOP_THRESHOLD = AI_TABLE_FIELD_HEAD_HEIGHT / 2;
2348
+ const AI_TABLE_AUTO_SCROLL_BOTTOM_THRESHOLD = AI_TABLE_FIELD_HEAD_HEIGHT / 2;
2308
2349
 
2309
2350
  const MIN_COLUMN_WIDTH = 80;
2310
2351
  const DBL_CLICK_EDIT_TYPE = [
@@ -3867,6 +3908,18 @@ const castToString = (value) => {
3867
3908
  }
3868
3909
  return typeof value !== 'string' ? String(value) : value;
3869
3910
  };
3911
+ // copy from plait
3912
+ function isVirtualKey(e) {
3913
+ const isMod = e.ctrlKey || e.metaKey;
3914
+ const isAlt = isKeyHotkey('alt', e);
3915
+ const isShift = isKeyHotkey('shift', e);
3916
+ const isCapsLock = e.key.includes('CapsLock');
3917
+ const isTab = e.key.includes('Tab');
3918
+ const isEsc = e.key.includes('Escape');
3919
+ const isF = e.key.startsWith('F');
3920
+ const isArrow = e.key.includes('Arrow') ? true : false;
3921
+ return isCapsLock || isMod || isAlt || isArrow || isShift || isTab || isEsc || isF;
3922
+ }
3870
3923
 
3871
3924
  function getPlaceHolderCellsConfigs(options) {
3872
3925
  const { aiTable, coordinate, columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex } = options;
@@ -5284,9 +5337,27 @@ class Drawer {
5284
5337
  }
5285
5338
  const drawer = new Drawer();
5286
5339
 
5287
- class AITableCellLink {
5340
+ class HoverCellComponent extends Component {
5288
5341
  constructor() {
5342
+ super(...arguments);
5289
5343
  this.config = input();
5344
+ this.onlyDisplayBorder = input(false);
5345
+ }
5346
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: HoverCellComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
5347
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.10", type: HoverCellComponent, isStandalone: true, selector: "ai-table-hover-cell", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, onlyDisplayBorder: { classPropertyName: "onlyDisplayBorder", publicName: "onlyDisplayBorder", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5348
+ }
5349
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: HoverCellComponent, decorators: [{
5350
+ type: Component,
5351
+ args: [{
5352
+ selector: 'ai-table-hover-cell',
5353
+ template: '',
5354
+ changeDetection: ChangeDetectionStrategy.OnPush
5355
+ }]
5356
+ }] });
5357
+
5358
+ class AITableCellLink extends HoverCellComponent {
5359
+ constructor() {
5360
+ super(...arguments);
5290
5361
  this.textOffset = AI_TABLE_CELL_PADDING + AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE;
5291
5362
  this.render = computed(() => this.config()?.render);
5292
5363
  this.transformValue = computed(() => this.render()?.transformValue);
@@ -5344,8 +5415,8 @@ class AITableCellLink {
5344
5415
  const curMousePosition = getMousePosition(aiTable, x, y, coordinate, AITable.getVisibleFields(aiTable), context, targetName);
5345
5416
  handleMouseStyle(AI_TABLE_FIELD_HEAD_MORE, curMousePosition.areaType, coordinate.container);
5346
5417
  }
5347
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCellLink, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5348
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableCellLink, isStandalone: true, selector: "ai-table-link", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
5418
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCellLink, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
5419
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableCellLink, isStandalone: true, selector: "ai-table-link", usesInheritance: true, ngImport: i0, template: `
5349
5420
  @if (showLink()) {
5350
5421
  <ai-table-text [config]="textConfig()!" (koClick)="linkClick($event)" (koMouseMove)="linkMouseMove($event)"></ai-table-text>
5351
5422
  }
@@ -5474,9 +5545,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
5474
5545
  }]
5475
5546
  }] });
5476
5547
 
5477
- class AITableCellAttachment {
5548
+ class AITableCellAttachment extends HoverCellComponent {
5478
5549
  constructor() {
5479
- this.config = input();
5550
+ super(...arguments);
5480
5551
  this.attachments = computed(() => {
5481
5552
  const { render, aiTable, field, recordId, readonly } = this.config();
5482
5553
  if (render) {
@@ -5550,8 +5621,8 @@ class AITableCellAttachment {
5550
5621
  });
5551
5622
  }
5552
5623
  static { this.fieldType = AITableFieldType.attachment; }
5553
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCellAttachment, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5554
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableCellAttachment, isStandalone: true, selector: "ai-table-attachments", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
5624
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCellAttachment, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
5625
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableCellAttachment, isStandalone: true, selector: "ai-table-attachments", usesInheritance: true, ngImport: i0, template: `
5555
5626
  @for (attachment of attachments(); track attachment.attachmentInfo._id) {
5556
5627
  <ko-image [config]="attachment"></ko-image>
5557
5628
  }
@@ -5573,9 +5644,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
5573
5644
  }]
5574
5645
  }] });
5575
5646
 
5576
- class AITableCellRichText {
5647
+ class AITableCellRichText extends HoverCellComponent {
5577
5648
  constructor() {
5578
- this.config = input();
5649
+ super(...arguments);
5579
5650
  this.textConfig = computed(() => {
5580
5651
  const render = this.config()?.render;
5581
5652
  if (render) {
@@ -5635,8 +5706,8 @@ class AITableCellRichText {
5635
5706
  });
5636
5707
  }
5637
5708
  static { this.fieldType = AITableFieldType.richText; }
5638
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCellRichText, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5639
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableCellRichText, isStandalone: true, selector: "ai-table-rich-text", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
5709
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCellRichText, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
5710
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableCellRichText, isStandalone: true, selector: "ai-table-rich-text", usesInheritance: true, ngImport: i0, template: `
5640
5711
  @if (textConfig()) {
5641
5712
  <ai-table-text [config]="textConfig()!"></ai-table-text>
5642
5713
  }
@@ -5671,7 +5742,8 @@ const createActiveCellBorder = (config) => {
5671
5742
  if (Array.isArray(activeCell) &&
5672
5743
  !!activeCell.length &&
5673
5744
  aiTable.context.visibleRowsIndexMap().has(activeCell[0]) &&
5674
- aiTable.context.visibleColumnsIndexMap().has(activeCell[1])) {
5745
+ aiTable.context.visibleColumnsIndexMap().has(activeCell[1]) &&
5746
+ !aiTable.selection().expandCell) {
5675
5747
  const fieldId = activeCell[1];
5676
5748
  const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, activeCell);
5677
5749
  const checkIsVisible = (rowIndex, columnIndex) => {
@@ -7287,6 +7359,9 @@ const getCellBackground = (cell, isHover, targetName, aiTable) => {
7287
7359
  if (isSelectedField(fieldId, aiTable) || isSelectedCell(cell, aiTable)) {
7288
7360
  return colors.itemActiveBgColor;
7289
7361
  }
7362
+ if (isKeywordsMatchedCell(cell, aiTable)) {
7363
+ return colors.itemMatchBgColor;
7364
+ }
7290
7365
  return getRowBackground(cell, isHover, targetName, aiTable);
7291
7366
  };
7292
7367
  const getIndexCellBackground = (cell, isHover, targetName, aiTable) => {
@@ -8288,27 +8363,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
8288
8363
  class AITableHoverCells {
8289
8364
  constructor() {
8290
8365
  this.config = input.required();
8366
+ this.onlyDisplayBorder = input(false);
8291
8367
  this.componentMap = {};
8292
8368
  this.groupConfig = computed(() => {
8293
8369
  return {
8294
8370
  x: this.hoverCellConfig()?.x,
8295
- y: this.hoverCellConfig()?.y
8371
+ y: this.hoverCellConfig()?.y,
8372
+ listening: true
8296
8373
  };
8297
8374
  });
8298
8375
  this.hoverCellConfig = computed(() => {
8299
8376
  const { aiTable, coordinate, references, readonly, actions } = this.config();
8300
- const pointPosition = aiTable.context.pointPosition();
8301
8377
  const hoverCell = this.hoverCell();
8302
8378
  if (!hoverCell) {
8303
8379
  return;
8304
8380
  }
8305
- const { field, recordId } = hoverCell;
8381
+ const { field, recordId, isExpand } = hoverCell;
8306
8382
  const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, field._id]);
8307
8383
  const fieldModel = FieldModelMap[field.type];
8308
8384
  const transformValue = fieldModel.transformCellValue(cellValue, { aiTable, field });
8309
8385
  const { rowHeight, columnCount, rowCount } = coordinate;
8310
- const columnIndex = pointPosition.columnIndex;
8311
- const rowIndex = pointPosition.rowIndex;
8386
+ const columnIndex = aiTable.context?.visibleColumnsIndexMap().get(field._id) ?? 0;
8387
+ const rowIndex = aiTable.context?.visibleRowsIndexMap().get(recordId) ?? 0;
8312
8388
  const x = coordinate.getColumnOffset(columnIndex) + AI_TABLE_OFFSET;
8313
8389
  const columnWidth = coordinate.getColumnWidth(columnIndex);
8314
8390
  const y = coordinate.getRowOffset(rowIndex) + AI_TABLE_OFFSET;
@@ -8334,6 +8410,7 @@ class AITableHoverCells {
8334
8410
  y,
8335
8411
  readonly,
8336
8412
  actions,
8413
+ isExpand,
8337
8414
  render: {
8338
8415
  aiTable,
8339
8416
  recordId,
@@ -8354,10 +8431,15 @@ class AITableHoverCells {
8354
8431
  this.hoverCell = computed(() => getHoverCell(this.config().aiTable));
8355
8432
  }
8356
8433
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableHoverCells, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8357
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableHoverCells, isStandalone: true, selector: "ai-table-hover-cell", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
8434
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableHoverCells, isStandalone: true, selector: "ai-table-hover-cell", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, onlyDisplayBorder: { classPropertyName: "onlyDisplayBorder", publicName: "onlyDisplayBorder", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
8358
8435
  @if (hoverCell()) {
8359
8436
  <ko-group [config]="groupConfig()">
8360
- <ng-container *ngComponentOutlet="hoverCell()!.renderComponentDefinition; inputs: { config: hoverCellConfig() }">
8437
+ <ng-container
8438
+ *ngComponentOutlet="
8439
+ hoverCell()!.renderComponentDefinition;
8440
+ inputs: { config: hoverCellConfig(), onlyDisplayBorder: onlyDisplayBorder() }
8441
+ "
8442
+ >
8361
8443
  </ng-container>
8362
8444
  </ko-group>
8363
8445
  }
@@ -8370,7 +8452,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
8370
8452
  template: `
8371
8453
  @if (hoverCell()) {
8372
8454
  <ko-group [config]="groupConfig()">
8373
- <ng-container *ngComponentOutlet="hoverCell()!.renderComponentDefinition; inputs: { config: hoverCellConfig() }">
8455
+ <ng-container
8456
+ *ngComponentOutlet="
8457
+ hoverCell()!.renderComponentDefinition;
8458
+ inputs: { config: hoverCellConfig(), onlyDisplayBorder: onlyDisplayBorder() }
8459
+ "
8460
+ >
8374
8461
  </ng-container>
8375
8462
  </ko-group>
8376
8463
  }
@@ -8463,19 +8550,11 @@ class AITableRenderer {
8463
8550
  clipHeight: this.containerHeight() - this.coordinate().rowInitSize
8464
8551
  };
8465
8552
  });
8466
- this.hoverAttachGroupConfig = computed(() => {
8467
- return {
8468
- clipX: this.frozenAreaWidth() + 1,
8469
- clipY: this.coordinate().rowInitSize + 1,
8470
- clipWidth: this.containerWidth() - this.frozenAreaWidth(),
8471
- clipHeight: this.containerHeight() - this.coordinate().rowInitSize
8472
- };
8473
- });
8474
8553
  this.frozenAttachGroupConfig = computed(() => {
8475
8554
  return {
8476
8555
  clipX: 0,
8477
8556
  clipY: this.coordinate().rowInitSize - 1,
8478
- clipWidth: this.frozenAreaWidth() + 4,
8557
+ clipWidth: this.frozenAreaWidth(),
8479
8558
  clipHeight: this.containerHeight() - this.coordinate().rowInitSize
8480
8559
  };
8481
8560
  });
@@ -8483,7 +8562,7 @@ class AITableRenderer {
8483
8562
  return {
8484
8563
  clipX: 0,
8485
8564
  clipY: this.coordinate().rowInitSize + 1,
8486
- clipWidth: this.frozenAreaWidth() + 4,
8565
+ clipWidth: this.frozenAreaWidth(),
8487
8566
  clipHeight: this.containerHeight() - this.coordinate().rowInitSize
8488
8567
  };
8489
8568
  });
@@ -8542,6 +8621,26 @@ class AITableRenderer {
8542
8621
  this.activeCellBorderConfig = computed(() => {
8543
8622
  return createActiveCellBorder(this.cellsConfig());
8544
8623
  });
8624
+ this.showExpandCellBorder = computed(() => {
8625
+ let expandCellBorder = false;
8626
+ let frozenExpandCellBorder = false;
8627
+ const { aiTable } = this.config();
8628
+ const expandCellPath = aiTable.selection().expandCell;
8629
+ if (expandCellPath) {
8630
+ const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, expandCellPath);
8631
+ const isFrozenColumn = columnIndex < aiTable.context.frozenColumnCount();
8632
+ if (isFrozenColumn) {
8633
+ frozenExpandCellBorder = true;
8634
+ }
8635
+ else {
8636
+ expandCellBorder = true;
8637
+ }
8638
+ }
8639
+ return {
8640
+ expandCellBorder,
8641
+ frozenExpandCellBorder
8642
+ };
8643
+ });
8545
8644
  }
8546
8645
  stageMousemove(e) {
8547
8646
  this.koMousemove.emit(e);
@@ -8565,7 +8664,7 @@ class AITableRenderer {
8565
8664
  this.koMouseleave.emit(e);
8566
8665
  }
8567
8666
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8568
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableRenderer, isStandalone: true, selector: "ai-table-renderer", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { koMousemove: "koMousemove", koMousedown: "koMousedown", koMouseup: "koMouseup", koContextmenu: "koContextmenu", koWheel: "koWheel", koClick: "koClick", koDblclick: "koDblclick", koMouseleave: "koMouseleave" }, ngImport: i0, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n (koMouseleave)=\"stageMouseleave($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n @if (!hiddenIndexColumn()) {\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n }\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"hoverAttachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-hover-cell [config]=\"cellsConfig()\"></ai-table-hover-cell>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenHoverAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-hover-cell [config]=\"cellsConfig()\"></ai-table-hover-cell>\n </ko-group>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n", dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoStage, selector: "ko-stage", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableColumnHeads, selector: "ai-table-column-heads", inputs: ["config"] }, { kind: "component", type: AITableFrozenColumnHeads, selector: "ai-table-frozen-column-heads", inputs: ["config"] }, { kind: "component", type: AITableCells, selector: "ai-table-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenCells, selector: "ai-table-frozen-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenPlaceholderCells, selector: "ai-table-frozen-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITableHoverCells, selector: "ai-table-hover-cell", inputs: ["config"] }, { kind: "component", type: AITablePlaceholderCells, selector: "ai-table-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITableAddField, selector: "ai-table-add-field", inputs: ["config"] }, { kind: "component", type: AITableHoverRowHeads, selector: "ai-table-hover-row-heads", inputs: ["config"] }, { kind: "component", type: AITableOtherRows, selector: "ai-table-other-rows", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8667
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableRenderer, isStandalone: true, selector: "ai-table-renderer", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { koMousemove: "koMousemove", koMousedown: "koMousedown", koMouseup: "koMouseup", koContextmenu: "koContextmenu", koWheel: "koWheel", koClick: "koClick", koDblclick: "koDblclick", koMouseleave: "koMouseleave" }, ngImport: i0, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n (koMouseleave)=\"stageMouseleave($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n @if (!hiddenIndexColumn()) {\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n }\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n <ai-table-hover-cell [config]=\"cellsConfig()\"></ai-table-hover-cell>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n @if (showExpandCellBorder().expandCellBorder) {\n <ai-table-hover-cell [config]=\"cellsConfig()\" [onlyDisplayBorder]=\"true\"></ai-table-hover-cell>\n }\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenHoverAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-hover-cell [config]=\"cellsConfig()\"></ai-table-hover-cell>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n @if (showExpandCellBorder().frozenExpandCellBorder) {\n <ai-table-hover-cell [config]=\"cellsConfig()\" [onlyDisplayBorder]=\"true\"></ai-table-hover-cell>\n }\n </ko-group>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n", dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoStage, selector: "ko-stage", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableColumnHeads, selector: "ai-table-column-heads", inputs: ["config"] }, { kind: "component", type: AITableFrozenColumnHeads, selector: "ai-table-frozen-column-heads", inputs: ["config"] }, { kind: "component", type: AITableCells, selector: "ai-table-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenCells, selector: "ai-table-frozen-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenPlaceholderCells, selector: "ai-table-frozen-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITableHoverCells, selector: "ai-table-hover-cell", inputs: ["config", "onlyDisplayBorder"] }, { kind: "component", type: AITablePlaceholderCells, selector: "ai-table-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITableAddField, selector: "ai-table-add-field", inputs: ["config"] }, { kind: "component", type: AITableHoverRowHeads, selector: "ai-table-hover-row-heads", inputs: ["config"] }, { kind: "component", type: AITableOtherRows, selector: "ai-table-other-rows", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8569
8668
  }
8570
8669
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableRenderer, decorators: [{
8571
8670
  type: Component,
@@ -8583,18 +8682,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
8583
8682
  AITableAddField,
8584
8683
  AITableHoverRowHeads,
8585
8684
  AITableOtherRows
8586
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n (koMouseleave)=\"stageMouseleave($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n @if (!hiddenIndexColumn()) {\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n }\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"hoverAttachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-hover-cell [config]=\"cellsConfig()\"></ai-table-hover-cell>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenHoverAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-hover-cell [config]=\"cellsConfig()\"></ai-table-hover-cell>\n </ko-group>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n" }]
8685
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n (koMouseleave)=\"stageMouseleave($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n @if (!hiddenIndexColumn()) {\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n }\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n <ai-table-hover-cell [config]=\"cellsConfig()\"></ai-table-hover-cell>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n @if (showExpandCellBorder().expandCellBorder) {\n <ai-table-hover-cell [config]=\"cellsConfig()\" [onlyDisplayBorder]=\"true\"></ai-table-hover-cell>\n }\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenHoverAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-hover-cell [config]=\"cellsConfig()\"></ai-table-hover-cell>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n @if (showExpandCellBorder().frozenExpandCellBorder) {\n <ai-table-hover-cell [config]=\"cellsConfig()\" [onlyDisplayBorder]=\"true\"></ai-table-hover-cell>\n }\n </ko-group>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n" }]
8587
8686
  }] });
8588
8687
 
8589
- class HoverCellComponent extends Component {
8590
- }
8591
-
8592
- class AITableCellRate {
8688
+ class AITableCellRate extends HoverCellComponent {
8593
8689
  constructor() {
8690
+ super(...arguments);
8594
8691
  this.pointerX = signal(0);
8595
8692
  this.pointerY = signal(0);
8596
8693
  this.resetStatus = signal(false);
8597
- this.config = input();
8598
8694
  this.readonly = computed(() => {
8599
8695
  return this.config()?.readonly;
8600
8696
  });
@@ -8706,8 +8802,8 @@ class AITableCellRate {
8706
8802
  });
8707
8803
  }
8708
8804
  }
8709
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCellRate, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8710
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableCellRate, isStandalone: true, selector: "ai-table-rate", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
8805
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCellRate, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
8806
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableCellRate, isStandalone: true, selector: "ai-table-rate", usesInheritance: true, ngImport: i0, template: `
8711
8807
  @if (!readonly()) {
8712
8808
  <ko-rect [config]="whiteBgConfig()" (koMousemove)="koMousemove($event)"></ko-rect>
8713
8809
  }
@@ -8733,9 +8829,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
8733
8829
  }]
8734
8830
  }] });
8735
8831
 
8736
- class AITableCellProgress {
8832
+ class AITableCellProgress extends HoverCellComponent {
8737
8833
  constructor() {
8738
- this.config = input();
8834
+ super(...arguments);
8739
8835
  this.readonly = computed(() => {
8740
8836
  return this.config()?.readonly;
8741
8837
  });
@@ -8952,8 +9048,8 @@ class AITableCellProgress {
8952
9048
  });
8953
9049
  }
8954
9050
  }
8955
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCellProgress, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8956
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableCellProgress, isStandalone: true, selector: "ai-table-progress", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
9051
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableCellProgress, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
9052
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableCellProgress, isStandalone: true, selector: "ai-table-progress", usesInheritance: true, ngImport: i0, template: `
8957
9053
  @if (!readonly()) {
8958
9054
  <ko-rect [config]="whiteBgConfig()"></ko-rect>
8959
9055
  }
@@ -9009,7 +9105,22 @@ Object.values(cellComponents).forEach((cellComponent) => {
9009
9105
 
9010
9106
  function getHoverCell(aiTable) {
9011
9107
  const pointPosition = aiTable.context.pointPosition();
9012
- const { fieldId, recordId } = getDetailByTargetName(pointPosition.realTargetName) ?? {};
9108
+ let fieldId;
9109
+ let recordId;
9110
+ const expandCell = aiTable.selection().expandCell;
9111
+ if (expandCell) {
9112
+ fieldId = expandCell[1];
9113
+ recordId = expandCell[0];
9114
+ }
9115
+ else {
9116
+ const { fieldId: fieldIdDetail, recordId: recordIdDetail } = getDetailByTargetName(pointPosition.realTargetName) ?? {};
9117
+ if (fieldIdDetail) {
9118
+ fieldId = fieldIdDetail;
9119
+ }
9120
+ if (recordIdDetail) {
9121
+ recordId = recordIdDetail;
9122
+ }
9123
+ }
9013
9124
  if (!recordId || !fieldId) {
9014
9125
  return;
9015
9126
  }
@@ -9026,6 +9137,7 @@ function getHoverCell(aiTable) {
9026
9137
  field,
9027
9138
  recordId,
9028
9139
  fieldId,
9140
+ isExpand: !!expandCell,
9029
9141
  renderComponentDefinition
9030
9142
  };
9031
9143
  }
@@ -9052,6 +9164,45 @@ function clearCells(aiTable, actions) {
9052
9164
  }
9053
9165
  }
9054
9166
 
9167
+ function aiTableTextConfigToKonvaConfig(textConfig, rowHeight) {
9168
+ const result = {
9169
+ x: textConfig.x,
9170
+ y: textConfig.y,
9171
+ text: textConfig.text,
9172
+ fill: textConfig.fillStyle,
9173
+ fontStyle: textConfig.fontWeight,
9174
+ fontSize: textConfig.fontSize,
9175
+ align: textConfig.textAlign,
9176
+ height: 0,
9177
+ verticalAlign: textConfig.verticalAlign,
9178
+ textDecoration: textConfig.textDecoration
9179
+ };
9180
+ return result;
9181
+ }
9182
+ function aiTableImageConfigToKonvaConfig(imageConfig, options) {
9183
+ let image = imageCache.getImage(imageConfig.url);
9184
+ if (!image) {
9185
+ const img = new Image();
9186
+ img.src = imageConfig.url;
9187
+ image = img;
9188
+ }
9189
+ const result = {
9190
+ ...imageConfig,
9191
+ listening: options?.listening,
9192
+ image: image
9193
+ };
9194
+ return result;
9195
+ }
9196
+ function aiTableRectConfigToKonvaConfig(rectConfig, options) {
9197
+ const result = {
9198
+ name: options?.name,
9199
+ ...rectConfig,
9200
+ cornerRadius: rectConfig.radius,
9201
+ listening: options?.listening ?? false
9202
+ };
9203
+ return result;
9204
+ }
9205
+
9055
9206
  class AITableGridEventService {
9056
9207
  constructor() {
9057
9208
  this.dblClickEvent$ = new Subject();
@@ -9139,7 +9290,7 @@ class AITableGridEventService {
9139
9290
  return ref;
9140
9291
  }
9141
9292
  getOriginPosition(aiTable, options) {
9142
- const { container, coordinate, recordId, fieldId, isHoverEdit } = options;
9293
+ const { container, coordinate, recordId, fieldId } = options;
9143
9294
  const { scrollState } = aiTable.context;
9144
9295
  const { rowHeight, columnCount } = coordinate;
9145
9296
  const cell = [recordId, fieldId];
@@ -9166,13 +9317,6 @@ class AITableGridEventService {
9166
9317
  let y = originPosition.y + getEditorBoxOffset();
9167
9318
  let width = getEditorSpace(originPosition.width);
9168
9319
  let height = getEditorSpace(originPosition.height);
9169
- // hover 编辑组件无边框
9170
- if (isHoverEdit) {
9171
- x = originPosition.x + getHoverEditorBoxOffset();
9172
- y = originPosition.y + getHoverEditorBoxOffset();
9173
- width = getHoverEditorSpace(originPosition.width);
9174
- height = getHoverEditorSpace(originPosition.height);
9175
- }
9176
9320
  return {
9177
9321
  ...originPosition,
9178
9322
  x: x,
@@ -9182,7 +9326,7 @@ class AITableGridEventService {
9182
9326
  };
9183
9327
  }
9184
9328
  openCellEditor(aiTable, options) {
9185
- const { container, recordId, fieldId, isHoverEdit, references } = options;
9329
+ const { container, recordId, fieldId, references } = options;
9186
9330
  const fieldType = this.aiTable.fieldsMap()[fieldId].type;
9187
9331
  const { component, isInternalComponent } = this.getEditorComponent(fieldType);
9188
9332
  const offsetOriginPosition = this.getOriginPosition(aiTable, options);
@@ -9199,7 +9343,8 @@ class AITableGridEventService {
9199
9343
  fieldId: fieldId,
9200
9344
  recordId: recordId,
9201
9345
  references,
9202
- aiTable: aiTable
9346
+ aiTable: aiTable,
9347
+ isSelectAll: options.isSelectAll,
9203
9348
  },
9204
9349
  panelClass: 'grid-cell-editor',
9205
9350
  outsideClosable: fieldType === AITableFieldType.link ? true : false,
@@ -9473,17 +9618,219 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
9473
9618
  ], 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" }]
9474
9619
  }] });
9475
9620
 
9621
+ class AITableScrollControllerService {
9622
+ constructor(ngZone) {
9623
+ this.ngZone = ngZone;
9624
+ this.animationFrame = null;
9625
+ this.mouseUpSubscription = null;
9626
+ this.isAutoScrolling = false;
9627
+ this.autoScrollSub = null;
9628
+ this.edgeDistanceX = 0;
9629
+ this.edgeDistanceY = 0;
9630
+ this.lastAutoScrollOptions = null;
9631
+ this.ngZone.runOutsideAngular(() => {
9632
+ this.mouseUpSubscription = fromEvent(document, 'mouseup').subscribe(() => {
9633
+ this.handleMouseUp();
9634
+ });
9635
+ });
9636
+ }
9637
+ scroll(options) {
9638
+ const { needScroll } = this.calculateScrollDistance(options);
9639
+ if (!needScroll) {
9640
+ this.isAutoScrolling = false;
9641
+ return;
9642
+ }
9643
+ this.lastAutoScrollOptions = options;
9644
+ if (!this.isAutoScrolling) {
9645
+ this.startAutoScroll(options);
9646
+ }
9647
+ }
9648
+ handleMouseUp() {
9649
+ this.isAutoScrolling = false;
9650
+ if (this.autoScrollSub) {
9651
+ this.autoScrollSub.unsubscribe();
9652
+ this.autoScrollSub = null;
9653
+ }
9654
+ this.isAutoScrolling = false;
9655
+ }
9656
+ startAutoScroll(options) {
9657
+ if (this.autoScrollSub) {
9658
+ this.autoScrollSub.unsubscribe();
9659
+ this.autoScrollSub = null;
9660
+ }
9661
+ this.isAutoScrolling = true;
9662
+ this.ngZone.runOutsideAngular(() => {
9663
+ this.autoScrollSub = animationFrames()
9664
+ .pipe(takeWhile(() => this.isAutoScrolling), map(() => {
9665
+ const currentOptions = this.lastAutoScrollOptions || options;
9666
+ let currentScrollX = 0;
9667
+ let currentScrollY = 0;
9668
+ const { horizontalElement, verticalElement } = currentOptions.scrollableElement;
9669
+ if (horizontalElement) {
9670
+ currentScrollX = horizontalElement.scrollLeft;
9671
+ }
9672
+ if (verticalElement) {
9673
+ currentScrollY = verticalElement.scrollTop;
9674
+ }
9675
+ // 计算最新滚动距离和速度
9676
+ const { scrollResult } = this.calculateScrollDistance(currentOptions);
9677
+ let left = 0;
9678
+ let top = 0;
9679
+ if (horizontalElement && scrollResult.speedX !== undefined && scrollResult.speedX !== 0) {
9680
+ left = Math.max(0, currentScrollX + scrollResult.speedX);
9681
+ horizontalElement.scrollLeft = left;
9682
+ }
9683
+ if (verticalElement && scrollResult.speedY !== undefined && scrollResult.speedY !== 0) {
9684
+ top = Math.max(0, currentScrollY + scrollResult.speedY);
9685
+ verticalElement.scrollTop = top;
9686
+ }
9687
+ this.isAutoScrolling = left !== 0 || top !== 0;
9688
+ return {
9689
+ x: horizontalElement?.scrollLeft || 0,
9690
+ y: verticalElement?.scrollTop || 0
9691
+ };
9692
+ }))
9693
+ .subscribe((position) => {
9694
+ options.onScrollChange?.({ x: position.x, y: position.y }, this.isAutoScrolling);
9695
+ });
9696
+ });
9697
+ }
9698
+ getEdgeThreshold(threshold, direction) {
9699
+ const defaultThreshold = 10; // 默认阈值
9700
+ if (isObject(threshold)) {
9701
+ return threshold[direction] || defaultThreshold;
9702
+ }
9703
+ return threshold || defaultThreshold;
9704
+ }
9705
+ // 计算距离和滚动速度
9706
+ calculateScrollDistance(options) {
9707
+ const { container, target, direction = 'both', scrollableElement, frozenArea = {}, edgeThreshold = 0, minScrollSpeed = 1, maxScrollSpeed = 20, scrollSpeedFactor = 1 } = options;
9708
+ const { horizontalElement, verticalElement } = scrollableElement;
9709
+ // 初始化滚动结果
9710
+ const scrollResult = {
9711
+ x: 0,
9712
+ y: 0,
9713
+ speedX: 0,
9714
+ speedY: 0
9715
+ };
9716
+ let needScroll = false;
9717
+ // 水平滚动计算
9718
+ if ((direction === 'horizontal' || direction === 'both') && horizontalElement) {
9719
+ const minLeft = frozenArea.left || 0;
9720
+ const maxLeft = frozenArea.right || container.width;
9721
+ const leftEdgeThreshold = this.getEdgeThreshold(edgeThreshold, 'left');
9722
+ const rightEdgeThreshold = this.getEdgeThreshold(edgeThreshold, 'right');
9723
+ if (target.x < minLeft + leftEdgeThreshold) {
9724
+ this.edgeDistanceX = Math.abs(minLeft + leftEdgeThreshold - target.x);
9725
+ // point点位离左边界阈值越远,速度越快
9726
+ const distanceFactor = Math.min(1.0, this.edgeDistanceX / leftEdgeThreshold);
9727
+ const speed = this.calculateSpeed(distanceFactor, minScrollSpeed, maxScrollSpeed, scrollSpeedFactor);
9728
+ scrollResult.x = this.edgeDistanceX;
9729
+ scrollResult.speedX = -speed; // 向左滚动
9730
+ needScroll = this.edgeDistanceX > 0;
9731
+ }
9732
+ else if (target.x + (target.width || 0) > maxLeft - rightEdgeThreshold) {
9733
+ const rightEdge = target.x + (target.width || 0);
9734
+ this.edgeDistanceX = Math.abs(rightEdge - maxLeft + rightEdgeThreshold);
9735
+ const distanceFactor = Math.min(1.0, this.edgeDistanceX / rightEdgeThreshold);
9736
+ const speed = this.calculateSpeed(distanceFactor, minScrollSpeed, maxScrollSpeed, scrollSpeedFactor);
9737
+ scrollResult.x = this.edgeDistanceX;
9738
+ scrollResult.speedX = speed;
9739
+ needScroll = this.edgeDistanceX > 0;
9740
+ }
9741
+ else {
9742
+ this.edgeDistanceX = 0;
9743
+ scrollResult.speedX = 0;
9744
+ }
9745
+ }
9746
+ // 垂直滚动计算
9747
+ if ((direction === 'vertical' || direction === 'both') && verticalElement) {
9748
+ const minTop = frozenArea.top || 0;
9749
+ const maxTop = frozenArea.bottom || container.height;
9750
+ const topEdgeThreshold = this.getEdgeThreshold(edgeThreshold, 'top');
9751
+ const bottomEdgeThreshold = this.getEdgeThreshold(edgeThreshold, 'bottom');
9752
+ if (target.y < minTop + topEdgeThreshold) {
9753
+ // 滚动距离
9754
+ this.edgeDistanceY = Math.abs(minTop + topEdgeThreshold - target.y);
9755
+ const distanceFactor = Math.min(1.0, this.edgeDistanceY / topEdgeThreshold);
9756
+ const speed = this.calculateSpeed(distanceFactor, minScrollSpeed, maxScrollSpeed, scrollSpeedFactor);
9757
+ scrollResult.y = this.edgeDistanceY;
9758
+ scrollResult.speedY = -speed; // 负值表示向上滚动
9759
+ needScroll = this.edgeDistanceY > 0;
9760
+ }
9761
+ else if (target.y + (target.height || 0) > maxTop - bottomEdgeThreshold) {
9762
+ // 向下滚动
9763
+ this.edgeDistanceY = Math.abs(target.y + (target.height || 0) - maxTop + bottomEdgeThreshold);
9764
+ const distanceFactor = Math.min(1.0, this.edgeDistanceY / bottomEdgeThreshold);
9765
+ const speed = this.calculateSpeed(distanceFactor, minScrollSpeed, maxScrollSpeed, scrollSpeedFactor);
9766
+ scrollResult.y = this.edgeDistanceY;
9767
+ scrollResult.speedY = speed;
9768
+ needScroll = this.edgeDistanceY > 0;
9769
+ }
9770
+ else {
9771
+ // 不在边缘区域,重置边缘距离
9772
+ this.edgeDistanceY = 0;
9773
+ scrollResult.speedY = 0;
9774
+ }
9775
+ }
9776
+ return { scrollResult, needScroll };
9777
+ }
9778
+ /**
9779
+ * 计算滚动速度
9780
+ * @param distanceFactor 距离因子(0-1)
9781
+ * @param minSpeed 最小速度
9782
+ * @param maxSpeed 最大速度
9783
+ * @param speedFactor 速度因子
9784
+ * @returns 计算后的滚动速度
9785
+ */
9786
+ calculateSpeed(distanceFactor, minSpeed, maxSpeed, speedFactor) {
9787
+ // 二次曲线计算,距离因子越大速度增长越快
9788
+ const easedFactor = distanceFactor * distanceFactor;
9789
+ // 计算最终速度,范围为 minSpeed 到 maxSpeed 之间
9790
+ const speed = minSpeed + (maxSpeed - minSpeed) * easedFactor;
9791
+ // 应用全局速度因子
9792
+ return speed * speedFactor;
9793
+ }
9794
+ destroy() {
9795
+ if (this.animationFrame) {
9796
+ cancelAnimationFrame(this.animationFrame);
9797
+ this.animationFrame = null;
9798
+ }
9799
+ if (this.autoScrollSub) {
9800
+ this.autoScrollSub.unsubscribe();
9801
+ this.autoScrollSub = null;
9802
+ }
9803
+ if (this.mouseUpSubscription) {
9804
+ this.mouseUpSubscription.unsubscribe();
9805
+ this.mouseUpSubscription = null;
9806
+ }
9807
+ }
9808
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableScrollControllerService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); }
9809
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableScrollControllerService }); }
9810
+ }
9811
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableScrollControllerService, decorators: [{
9812
+ type: Injectable
9813
+ }], ctorParameters: () => [{ type: i0.NgZone }] });
9814
+
9476
9815
  class AITableDragComponent {
9477
9816
  constructor() {
9817
+ this.horizontalBar = input();
9818
+ this.verticalBar = input();
9478
9819
  this.dragEnd = output();
9479
9820
  this.aiTableGridSelectionService = inject(AITableGridSelectionService);
9480
9821
  this.render2 = inject(Renderer2);
9822
+ this.scrollControllerService = inject(AITableScrollControllerService);
9481
9823
  this.elementRef = inject((ElementRef));
9482
9824
  this.draggedData = null;
9825
+ this.scrollBarStartPosition = { x: 0, y: 0 };
9483
9826
  this.mouseStartPosition = null;
9484
9827
  this.aiTableDrag = null;
9485
9828
  this.mouseDownTimeout = null;
9486
9829
  this.isDraggingEnabled = false;
9830
+ this.containerWidth = 0;
9831
+ this.containerHeight = 0;
9832
+ this.horizontalBarMaxScroll = 0;
9833
+ this.verticalBarMaxScroll = 0;
9487
9834
  effect(() => this.handleDragStateChange());
9488
9835
  }
9489
9836
  ngOnInit() {
@@ -9501,6 +9848,11 @@ class AITableDragComponent {
9501
9848
  clearTimeout(this.mouseDownTimeout);
9502
9849
  }
9503
9850
  this.isDraggingEnabled = false;
9851
+ this.horizontalBarElement = this.horizontalBar()?.nativeElement;
9852
+ this.horizontalBarMaxScroll = (this.horizontalBarElement?.scrollWidth || 0) - (this.horizontalBarElement?.clientWidth || 0);
9853
+ this.verticalBarElement = this.verticalBar()?.nativeElement;
9854
+ this.verticalBarMaxScroll = (this.verticalBarElement?.scrollHeight || 0) - (this.verticalBarElement?.clientHeight || 0);
9855
+ this.scrollBarStartPosition = { x: this.horizontalBarElement?.scrollLeft || 0, y: this.verticalBarElement?.scrollTop || 0 };
9504
9856
  this.mouseDownTimeout = setTimeout(() => {
9505
9857
  this.isDraggingEnabled = true;
9506
9858
  }, 200);
@@ -9545,6 +9897,8 @@ class AITableDragComponent {
9545
9897
  return;
9546
9898
  }
9547
9899
  this.setDisplayStyle('block');
9900
+ this.containerWidth = this.elementRef.nativeElement.offsetWidth;
9901
+ this.containerHeight = this.elementRef.nativeElement.offsetHeight;
9548
9902
  const moveX = e.x - (this.mouseStartPosition?.x || 0);
9549
9903
  const moveY = e.y - (this.mouseStartPosition?.y || 0);
9550
9904
  switch (drag.type) {
@@ -9561,7 +9915,7 @@ class AITableDragComponent {
9561
9915
  }
9562
9916
  movingColumn(drag, moveX) {
9563
9917
  const aiTable = this.aiTableGridSelectionService.aiTable;
9564
- const scroll = drag.scroll || { x: 0, y: 0 };
9918
+ const scroll = { x: this.horizontalBarElement?.scrollLeft || 0, y: 0 };
9565
9919
  const coordinate = drag.coordinate;
9566
9920
  const fields = aiTable.gridData().fields;
9567
9921
  const width = this.calculateDragWidth(fields, coordinate, drag);
@@ -9575,60 +9929,102 @@ class AITableDragComponent {
9575
9929
  const pointerX = moveX + sourceColumnStartX;
9576
9930
  // 拖拽中心点
9577
9931
  const dragCenter = sourceColumnWidth / 2;
9578
- const rectLeft = pointerX - (isSourceColumnFrozen ? 0 : scroll.x);
9932
+ const currentRectLeft = pointerX - (isSourceColumnFrozen ? 0 : this.scrollBarStartPosition.x);
9933
+ let newScrollPosition = { x: scroll.x, y: scroll.y };
9579
9934
  this.setRectStyles({
9580
9935
  cursor: 'move',
9581
9936
  width: `${width}px`,
9582
9937
  height: '100%',
9583
9938
  top: '0',
9584
- left: `${rectLeft}px`
9585
- });
9586
- const lastColumnOffset = coordinate.getColumnOffset(coordinate.columnCount - 1);
9587
- const lastColumnWidth = coordinate.getColumnWidth(coordinate.columnCount - 1);
9588
- let targetColumnIndex = coordinate.getColumnStartIndex(pointerX + (isSourceColumnFrozen ? scroll.x : 0) + dragCenter);
9589
- let targetColumnStartX = coordinate.getColumnOffset(targetColumnIndex);
9590
- let isLastColumn = false;
9591
- // 处理最后一列
9592
- if (pointerX + dragCenter > lastColumnOffset + lastColumnWidth) {
9593
- targetColumnIndex = coordinate.columnCount;
9594
- targetColumnStartX = lastColumnOffset + lastColumnWidth;
9595
- isLastColumn = true;
9596
- }
9597
- if ((targetColumnIndex >= 0 && (targetColumnIndex - sourceColumnIndex > 1 || targetColumnIndex - sourceColumnIndex < 0)) ||
9598
- isLastColumn) {
9599
- let lineLeft = targetColumnStartX - scroll.x;
9600
- const lineForFrozenX = lineLeft - frozenColumnWidth - aiTable.context.rowHeadWidth();
9601
- const rectDistanceFrozenX = rectLeft - frozenColumnWidth - aiTable.context.rowHeadWidth();
9602
- if (lineForFrozenX < 0) {
9603
- if (Math.abs(rectDistanceFrozenX) > dragCenter) {
9604
- lineLeft = coordinate.getColumnOffset(0);
9605
- targetColumnIndex = 0;
9939
+ left: `${currentRectLeft}px`
9940
+ });
9941
+ // 计算目标列和辅助线
9942
+ const updateTargetAndLine = (rectLeft, scrollPosition) => {
9943
+ let targetColumnIndex = coordinate.getColumnStartIndex(rectLeft + scrollPosition.x + dragCenter);
9944
+ const lastColumnOffset = coordinate.getColumnOffset(coordinate.columnCount - 1);
9945
+ const lastColumnWidth = coordinate.getColumnWidth(coordinate.columnCount - 1);
9946
+ const lastColumnEndX = lastColumnOffset + lastColumnWidth;
9947
+ let targetColumnStartX = coordinate.getColumnOffset(targetColumnIndex);
9948
+ let isLastColumn = false;
9949
+ // 处理最后一列
9950
+ if (rectLeft + dragCenter + scrollPosition.x > lastColumnEndX) {
9951
+ targetColumnIndex = coordinate.columnCount;
9952
+ targetColumnStartX = lastColumnOffset + lastColumnWidth;
9953
+ isLastColumn = true;
9954
+ }
9955
+ if ((targetColumnIndex >= 0 && (targetColumnIndex - sourceColumnIndex > 1 || targetColumnIndex - sourceColumnIndex < 0)) ||
9956
+ isLastColumn) {
9957
+ let lineLeft = targetColumnStartX - scrollPosition.x;
9958
+ const lineForFrozenX = lineLeft - frozenColumnWidth - aiTable.context.rowHeadWidth();
9959
+ const rectDistanceFrozenX = rectLeft - frozenColumnWidth - aiTable.context.rowHeadWidth();
9960
+ if (lineForFrozenX < 0) {
9961
+ if (Math.abs(rectDistanceFrozenX) < dragCenter) {
9962
+ // 滚动中保持上一个位置
9963
+ const nextColumnStartX = coordinate.getColumnOffset(targetColumnIndex + 1);
9964
+ this.setAuxiliaryLineStyles({
9965
+ left: `${nextColumnStartX - scrollPosition.x}px`
9966
+ });
9967
+ this.draggedData = {
9968
+ type: DragType.field,
9969
+ targetIndex: targetColumnIndex + 1,
9970
+ fieldIds: drag.sourceIds,
9971
+ fieldsIndex: Array.from(drag.sourceIds).map((id) => visibleColumnIndexMap.get(id) || 0)
9972
+ };
9973
+ return;
9974
+ }
9606
9975
  }
9607
- else {
9608
- return;
9976
+ this.setAuxiliaryLineStyles({
9977
+ width: '2px',
9978
+ height: '100%',
9979
+ top: 0,
9980
+ left: `${lineLeft}px`
9981
+ });
9982
+ // 向右移动目标在目标列的前一列
9983
+ if (targetColumnIndex > sourceColumnIndex) {
9984
+ targetColumnIndex -= 1;
9609
9985
  }
9986
+ this.draggedData = {
9987
+ type: DragType.field,
9988
+ targetIndex: targetColumnIndex,
9989
+ fieldIds: drag.sourceIds,
9990
+ fieldsIndex: Array.from(drag.sourceIds).map((id) => visibleColumnIndexMap.get(id) || 0)
9991
+ };
9610
9992
  }
9611
- this.setAuxiliaryLineStyles({
9612
- width: '2px',
9613
- height: '100%',
9614
- top: 0,
9615
- left: `${lineLeft}px`
9616
- });
9617
- // 向右移动目标在目标列的前一列
9618
- if (targetColumnIndex > sourceColumnIndex) {
9619
- targetColumnIndex -= 1;
9993
+ else {
9994
+ this.resetAuxiliaryLine();
9995
+ this.draggedData = null;
9620
9996
  }
9621
- this.draggedData = {
9622
- type: DragType.field,
9623
- targetIndex: targetColumnIndex,
9624
- fieldIds: drag.sourceIds,
9625
- fieldsIndex: Array.from(drag.sourceIds).map((id) => visibleColumnIndexMap.get(id) || 0)
9626
- };
9627
- }
9628
- else {
9629
- this.resetAuxiliaryLine();
9630
- this.draggedData = null;
9631
- }
9997
+ };
9998
+ updateTargetAndLine(currentRectLeft, newScrollPosition);
9999
+ this.scrollControllerService.scroll({
10000
+ container: {
10001
+ width: this.containerWidth,
10002
+ height: this.containerHeight
10003
+ },
10004
+ target: {
10005
+ x: currentRectLeft,
10006
+ y: 0,
10007
+ width: sourceColumnWidth,
10008
+ height: this.containerHeight
10009
+ },
10010
+ direction: 'horizontal',
10011
+ scrollableElement: {
10012
+ horizontalElement: this.horizontalBarElement
10013
+ },
10014
+ frozenArea: {
10015
+ left: frozenColumnWidth + aiTable.context.rowHeadWidth()
10016
+ },
10017
+ edgeThreshold: {
10018
+ left: AI_TABLE_AUTO_SCROLL_LEFT_THRESHOLD,
10019
+ right: AI_TABLE_SCROLL_BAR_SIZE + AI_TABLE_AUTO_SCROLL_RIGHT_THRESHOLD
10020
+ },
10021
+ onScrollChange: (position, isAutoScrolling) => {
10022
+ newScrollPosition = position;
10023
+ if (isAutoScrolling && position.x > 0 && Math.round(position.x) < this.horizontalBarMaxScroll) {
10024
+ updateTargetAndLine(currentRectLeft, position);
10025
+ }
10026
+ }
10027
+ });
9632
10028
  }
9633
10029
  movingColumnWidth(drag, moveX) {
9634
10030
  this.setCursorStyle('col-resize');
@@ -9637,7 +10033,7 @@ class AITableDragComponent {
9637
10033
  const sourceColumnIndex = visibleColumnIndexMap.get(drag.sourceIds.values().next().value) || 0;
9638
10034
  const sourceColumnStartX = drag.coordinate.getColumnOffset(sourceColumnIndex);
9639
10035
  const sourceColumnWidth = drag.coordinate.getColumnWidth(sourceColumnIndex);
9640
- const scroll = drag.scroll || { x: 0, y: 0 };
10036
+ const scroll = { x: this.horizontalBarElement?.scrollLeft || 0, y: this.verticalBarElement?.scrollTop || 0 };
9641
10037
  const pointerX = moveX + sourceColumnStartX;
9642
10038
  const colResizeX = pointerX - (sourceColumnIndex === 0 ? 0 : scroll.x);
9643
10039
  const left = `${colResizeX + sourceColumnWidth}px`;
@@ -9647,15 +10043,23 @@ class AITableDragComponent {
9647
10043
  top: '0',
9648
10044
  left
9649
10045
  });
10046
+ let minWidth = MIN_COLUMN_WIDTH;
10047
+ drag.sourceIds.forEach((id) => {
10048
+ const field = aiTable.fieldsMap()[id];
10049
+ const fieldOption = aiTable.context.fieldOptionMap().get(field.type);
10050
+ if (fieldOption && fieldOption.minWidth) {
10051
+ minWidth = Math.max(minWidth, fieldOption.minWidth);
10052
+ }
10053
+ });
9650
10054
  this.draggedData = {
9651
10055
  type: DragType.columnWidth,
9652
10056
  fieldIds: drag.sourceIds,
9653
- width: Math.max(MIN_COLUMN_WIDTH, sourceColumnWidth + moveX)
10057
+ width: Math.max(minWidth, sourceColumnWidth + moveX)
9654
10058
  };
9655
10059
  }
9656
10060
  movingRecord(drag, moveY) {
9657
10061
  const aiTable = this.aiTableGridSelectionService.aiTable;
9658
- const scroll = drag.scroll || { x: 0, y: 0 };
10062
+ const scroll = { x: 0, y: this.verticalBarElement?.scrollTop || 0 };
9659
10063
  const coordinate = drag.coordinate;
9660
10064
  const visibleRowIndexMap = aiTable.context.visibleRowsIndexMap();
9661
10065
  const sourceRowId = drag.sourceIds.values().next().value;
@@ -9663,37 +10067,82 @@ class AITableDragComponent {
9663
10067
  const sourceRowStartY = coordinate.getRowOffset(sourceRowIndex);
9664
10068
  const sourceRowHeight = coordinate.getRowHeight(sourceRowIndex);
9665
10069
  const pointerY = sourceRowStartY + moveY;
10070
+ const rectTop = pointerY - this.scrollBarStartPosition.y;
9666
10071
  this.setRectStyles({
9667
10072
  width: '100%',
9668
10073
  height: `${sourceRowHeight}px`,
9669
- top: `${pointerY - scroll.y}px`,
10074
+ top: `${rectTop}px`,
9670
10075
  left: '0'
9671
10076
  });
9672
- const dragCenter = sourceRowHeight / 2;
9673
- const targetRowIndex = coordinate.getRowStartIndex(pointerY + dragCenter);
9674
- const targetRowStartY = coordinate.getRowOffset(targetRowIndex);
9675
- const lineTop = targetRowStartY - scroll.y;
9676
- const lineHeight = 2;
9677
- if (((targetRowIndex >= 0 && sourceRowIndex > targetRowIndex && sourceRowIndex - targetRowIndex > 0) ||
9678
- (sourceRowIndex < targetRowIndex && targetRowIndex - sourceRowIndex > 1)) &&
9679
- lineTop > AI_TABLE_FIELD_HEAD_HEIGHT - lineHeight && // 限制可视范围内
9680
- lineTop < coordinate.containerHeight - lineHeight) {
9681
- this.setAuxiliaryLineStyles({
9682
- width: `calc(100% - ${AI_TABLE_ROW_DRAG_ICON_WIDTH}px)`,
9683
- height: `${lineHeight}px`,
9684
- top: `${lineTop}px`,
9685
- left: `${AI_TABLE_ROW_DRAG_ICON_WIDTH}px`
9686
- });
9687
- this.draggedData = {
9688
- type: DragType.record,
9689
- recordIds: drag.sourceIds,
9690
- targetIndex: targetRowIndex
9691
- };
9692
- }
9693
- else {
9694
- this.resetAuxiliaryLine();
9695
- this.draggedData = null;
9696
- }
10077
+ let newScrollPosition = { x: scroll.x, y: scroll.y };
10078
+ const updateTargetAndLine = (rectTop, scrollPosition) => {
10079
+ const dragCenter = sourceRowHeight / 2;
10080
+ const targetRowIndex = coordinate.getRowStartIndex(rectTop + scrollPosition.y + dragCenter);
10081
+ const targetRowStartY = coordinate.getRowOffset(targetRowIndex);
10082
+ const lineHeight = 2;
10083
+ if ((targetRowIndex >= 0 && sourceRowIndex > targetRowIndex && sourceRowIndex - targetRowIndex > 0) ||
10084
+ (sourceRowIndex < targetRowIndex && targetRowIndex - sourceRowIndex > 1)) {
10085
+ let lineTop = targetRowStartY - scrollPosition.y;
10086
+ if (lineTop < AI_TABLE_FIELD_HEAD_HEIGHT) {
10087
+ // 滚动中保持上一个位置
10088
+ const nextColumnStartY = coordinate.getRowOffset(targetRowIndex + 1);
10089
+ this.setAuxiliaryLineStyles({
10090
+ top: `${nextColumnStartY - scrollPosition.y}px`
10091
+ });
10092
+ this.draggedData = {
10093
+ type: DragType.record,
10094
+ recordIds: drag.sourceIds,
10095
+ targetIndex: targetRowIndex + 1
10096
+ };
10097
+ return;
10098
+ }
10099
+ this.setAuxiliaryLineStyles({
10100
+ width: `calc(100% - ${AI_TABLE_ROW_DRAG_ICON_WIDTH}px)`,
10101
+ height: `${lineHeight}px`,
10102
+ top: `${lineTop}px`,
10103
+ left: `${AI_TABLE_ROW_DRAG_ICON_WIDTH}px`
10104
+ });
10105
+ this.draggedData = {
10106
+ type: DragType.record,
10107
+ recordIds: drag.sourceIds,
10108
+ targetIndex: targetRowIndex
10109
+ };
10110
+ }
10111
+ else {
10112
+ this.resetAuxiliaryLine();
10113
+ this.draggedData = null;
10114
+ }
10115
+ };
10116
+ updateTargetAndLine(rectTop, newScrollPosition);
10117
+ this.scrollControllerService.scroll({
10118
+ container: {
10119
+ width: this.containerWidth,
10120
+ height: this.containerHeight
10121
+ },
10122
+ target: {
10123
+ x: 0,
10124
+ y: rectTop,
10125
+ width: this.containerWidth,
10126
+ height: sourceRowHeight
10127
+ },
10128
+ direction: 'vertical',
10129
+ scrollableElement: {
10130
+ verticalElement: this.verticalBarElement
10131
+ },
10132
+ frozenArea: {
10133
+ top: AI_TABLE_FIELD_HEAD_HEIGHT
10134
+ },
10135
+ edgeThreshold: {
10136
+ top: AI_TABLE_AUTO_SCROLL_TOP_THRESHOLD,
10137
+ bottom: AI_TABLE_AUTO_SCROLL_BOTTOM_THRESHOLD
10138
+ },
10139
+ onScrollChange: (position, isAutoScrolling) => {
10140
+ newScrollPosition = position;
10141
+ if (isAutoScrolling && position.y > 0 && position.y < this.verticalBarMaxScroll) {
10142
+ updateTargetAndLine(rectTop, newScrollPosition);
10143
+ }
10144
+ }
10145
+ });
9697
10146
  }
9698
10147
  handleDragEnd() {
9699
10148
  if (this.draggedData) {
@@ -9756,9 +10205,10 @@ class AITableDragComponent {
9756
10205
  cancelAnimationFrame(this.timer);
9757
10206
  this.timer = null;
9758
10207
  }
10208
+ this.scrollControllerService.destroy();
9759
10209
  }
9760
10210
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableDragComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9761
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.10", type: AITableDragComponent, isStandalone: true, selector: "ai-table-drag", outputs: { dragEnd: "dragEnd" }, host: { classAttribute: "ai-table-drag-container" }, ngImport: i0, template: "<div class=\"rect\"></div>\n<div class=\"auxiliary-line\"></div>", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
10211
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.10", type: AITableDragComponent, isStandalone: true, selector: "ai-table-drag", inputs: { horizontalBar: { classPropertyName: "horizontalBar", publicName: "horizontalBar", isSignal: true, isRequired: false, transformFunction: null }, verticalBar: { classPropertyName: "verticalBar", publicName: "verticalBar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragEnd: "dragEnd" }, host: { classAttribute: "ai-table-drag-container" }, ngImport: i0, template: "<div class=\"rect\"></div>\n<div class=\"auxiliary-line\"></div>", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9762
10212
  }
9763
10213
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableDragComponent, decorators: [{
9764
10214
  type: Component,
@@ -9774,6 +10224,7 @@ class AITableGrid extends AITableGridBase {
9774
10224
  this.isDragSelecting = false;
9775
10225
  this.dragSelectionStart = null;
9776
10226
  this.notifyService = inject(ThyNotifyService);
10227
+ this.scrollControllerService = inject(AITableScrollControllerService);
9777
10228
  this.isPopoverOpen = false;
9778
10229
  this.fieldHeadHeight = AI_TABLE_FIELD_HEAD_HEIGHT;
9779
10230
  this.containerRect = signal({ width: 0, height: 0 });
@@ -9808,6 +10259,26 @@ class AITableGrid extends AITableGridBase {
9808
10259
  const columns = AITable.getVisibleFields(this.aiTable);
9809
10260
  return new Map(columns?.map((item, index) => [item._id, index]));
9810
10261
  });
10262
+ this.fieldOptions = computed(() => {
10263
+ let allFieldOptions = defaultFieldOptions.map((fieldOption) => {
10264
+ fieldOption.name = getI18nTextByKey(this.aiTable, fieldOption.name);
10265
+ return fieldOption;
10266
+ });
10267
+ Object.entries(this.aiTable.context?.aiFieldConfig()?.customFields || {}).forEach(([fieldType, fieldConfig]) => {
10268
+ if (fieldConfig?.fieldOption) {
10269
+ allFieldOptions.push(fieldConfig.fieldOption);
10270
+ }
10271
+ });
10272
+ const fieldOptionMap = new Map(allFieldOptions.map((fieldOption) => [fieldOption.type, fieldOption]));
10273
+ const fieldOptionKeys = this.aiTable.context?.aiFieldConfig()?.fieldOptionKeys || [];
10274
+ if (fieldOptionKeys.length > 0) {
10275
+ allFieldOptions = fieldOptionKeys.map((fieldOptionKey) => fieldOptionMap.get(fieldOptionKey));
10276
+ }
10277
+ return allFieldOptions;
10278
+ });
10279
+ this.fieldOptionMap = computed(() => {
10280
+ return new Map(this.fieldOptions().map((fieldOption) => [fieldOption.type, fieldOption]));
10281
+ });
9811
10282
  this.visibleRowsIndexMap = computed(() => {
9812
10283
  return new Map(this.linearRows().map((row, index) => [row._id, index]));
9813
10284
  });
@@ -9854,6 +10325,13 @@ class AITableGrid extends AITableGridBase {
9854
10325
  this.scrollbarWidth = computed(() => {
9855
10326
  return this.coordinate().totalWidth + AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
9856
10327
  });
10328
+ this.i18nTexts = computed(() => {
10329
+ this.aiGetI18nTextByKey();
10330
+ return {
10331
+ rowAddFilterTooltip: getI18nTextByKey(this.aiTable, AITableGridI18nKey.rowAddFilterTooltip)
10332
+ };
10333
+ });
10334
+ // rowAddFilterTooltip = getI18nTextByKey(this.aiTable, AITableGridI18nKey.rowAddFilterTooltip);
9857
10335
  this.actions = {
9858
10336
  updateFieldValue: (data) => {
9859
10337
  this.aiUpdateFieldValue.emit(data);
@@ -9906,7 +10384,7 @@ class AITableGrid extends AITableGridBase {
9906
10384
  this.bindGlobalMousedown();
9907
10385
  this.containerResizeListener();
9908
10386
  this.bindWheel();
9909
- this.bindClipboardShortcuts();
10387
+ this.bindShortcuts();
9910
10388
  });
9911
10389
  effect(() => {
9912
10390
  if (this.hasContainerRect() && this.horizontalBarRef() && this.verticalBarRef()) {
@@ -9967,7 +10445,9 @@ class AITableGrid extends AITableGridBase {
9967
10445
  aiFieldConfig: this.aiFieldConfig,
9968
10446
  scrollAction: this.scrollAction,
9969
10447
  maxFields: this.aiMaxFields,
9970
- maxRecords: this.aiMaxRecords
10448
+ maxRecords: this.aiMaxRecords,
10449
+ fieldOptions: this.fieldOptions,
10450
+ fieldOptionMap: this.fieldOptionMap
9971
10451
  });
9972
10452
  }
9973
10453
  initCustomField() {
@@ -10029,6 +10509,7 @@ class AITableGrid extends AITableGridBase {
10029
10509
  const endCell = [recordId, fieldId];
10030
10510
  if (startCell && !!startCell.length) {
10031
10511
  this.aiTableGridSelectionService.selectCells(startCell, endCell);
10512
+ this.scrollViewToCell(pos, startCell, endCell, this.coordinate(), this.horizontalBarRef(), this.verticalBarRef());
10032
10513
  }
10033
10514
  }
10034
10515
  }
@@ -10063,7 +10544,10 @@ class AITableGrid extends AITableGridBase {
10063
10544
  return;
10064
10545
  const dragSelectionStart = [recordId, fieldId];
10065
10546
  this.updateDragSelectionState(true, dragSelectionStart);
10066
- this.aiTableGridSelectionService.selectCells(dragSelectionStart);
10547
+ const [expandRecordId, expandFieldId] = this.aiTable.selection().expandCell || [null, null];
10548
+ if (expandRecordId !== recordId || expandFieldId !== fieldId) {
10549
+ this.aiTableGridSelectionService.selectCells(dragSelectionStart);
10550
+ }
10067
10551
  return;
10068
10552
  case AI_TABLE_ROW_DRAG:
10069
10553
  if (!recordId)
@@ -10308,11 +10792,9 @@ class AITableGrid extends AITableGridBase {
10308
10792
  });
10309
10793
  this.resizeObserver.observe(this.containerElement());
10310
10794
  }
10311
- bindClipboardShortcuts() {
10795
+ bindShortcuts() {
10312
10796
  fromEvent(document, 'keydown')
10313
- .pipe(filter((event) => ((event.ctrlKey || event.metaKey) && (event.key === 'c' || event.key === 'v')) ||
10314
- event.key === 'Backspace' ||
10315
- event.key === 'Delete'), takeUntilDestroyed(this.destroyRef))
10797
+ .pipe(takeUntilDestroyed(this.destroyRef))
10316
10798
  .subscribe(async (event) => {
10317
10799
  if (this.aiReadonly()) {
10318
10800
  return;
@@ -10331,14 +10813,39 @@ class AITableGrid extends AITableGridBase {
10331
10813
  return;
10332
10814
  }
10333
10815
  event.preventDefault();
10334
- if (event.key === 'c') {
10335
- this.copyCells();
10336
- }
10337
- else if (event.key === 'v') {
10338
- this.pasteCells();
10816
+ const isCopyOrPaste = (event.ctrlKey || event.metaKey) && (event.key === 'c' || event.key === 'v');
10817
+ const isDeleteOrBackspace = event.key === 'Backspace' || event.key === 'Delete';
10818
+ if (isCopyOrPaste) {
10819
+ if (event.key === 'c') {
10820
+ this.copyCells();
10821
+ }
10822
+ else if (event.key === 'v') {
10823
+ this.pasteCells();
10824
+ }
10825
+ return;
10339
10826
  }
10340
- else if (event.key === 'Backspace' || event.key === 'Delete') {
10827
+ if (isDeleteOrBackspace) {
10341
10828
  clearCells(this.aiTable, this.actions);
10829
+ return;
10830
+ }
10831
+ // quick enter cell editor
10832
+ const isKeyForInput = !isVirtualKey(event);
10833
+ const activeCell = this.aiTable.selection().activeCell;
10834
+ const field = activeCell && this.aiTable.fieldsMap()[activeCell[1]];
10835
+ if (isKeyForInput && activeCell && field && field.type === AITableFieldType.text) {
10836
+ const [recordId, fieldId] = activeCell;
10837
+ this.aiTableGridEventService.openCellEditor(this.aiTable, {
10838
+ viewContainerRef: this.viewContainerRef,
10839
+ container: this.containerElement(),
10840
+ coordinate: this.coordinate(),
10841
+ fieldId,
10842
+ recordId,
10843
+ isSelectAll: true,
10844
+ references: this.aiReferences(),
10845
+ updateFieldValue: (value) => {
10846
+ this.aiUpdateFieldValue.emit(value);
10847
+ }
10848
+ });
10342
10849
  }
10343
10850
  });
10344
10851
  }
@@ -10368,41 +10875,31 @@ class AITableGrid extends AITableGridBase {
10368
10875
  }
10369
10876
  handleFieldDragStart() {
10370
10877
  if (!this.aiReadonly() && this.aiTableGridSelectionService.selectedFields.size > 0) {
10371
- this.aiTableGridSelectionService.drag({
10878
+ this.setDragState({
10372
10879
  type: DragType.field,
10373
10880
  sourceIds: this.aiTableGridSelectionService.selectedFields,
10374
- scroll: this.getScrollPosition(),
10375
10881
  coordinate: this.coordinate()
10376
10882
  });
10377
10883
  }
10378
10884
  }
10379
10885
  handleFieldWidthDragStart(fieldId) {
10380
10886
  if (!this.aiReadonly() && fieldId) {
10381
- this.aiTableGridSelectionService.drag({
10887
+ this.setDragState({
10382
10888
  type: DragType.columnWidth,
10383
10889
  sourceIds: new Set([fieldId]),
10384
- scroll: this.getScrollPosition(),
10385
10890
  coordinate: this.coordinate()
10386
10891
  });
10387
10892
  }
10388
10893
  }
10389
10894
  handleRowDragStart(recordIds) {
10390
10895
  if (!this.aiReadonly() && !this.aiRowDragDisabled() && recordIds.length > 0) {
10391
- this.aiTableGridSelectionService.drag({
10896
+ this.setDragState({
10392
10897
  type: DragType.record,
10393
10898
  sourceIds: new Set(recordIds),
10394
- scroll: this.getScrollPosition(),
10395
10899
  coordinate: this.coordinate()
10396
10900
  });
10397
10901
  }
10398
10902
  }
10399
- getScrollPosition() {
10400
- const horizontalBar = this.horizontalBarRef()?.nativeElement;
10401
- const verticalBar = this.verticalBarRef()?.nativeElement;
10402
- let scrollLeft = horizontalBar?.scrollLeft || 0;
10403
- let scrollTop = verticalBar?.scrollTop || 0;
10404
- return { x: scrollLeft, y: scrollTop };
10405
- }
10406
10903
  dragEnd(data) {
10407
10904
  switch (data.type) {
10408
10905
  case DragType.field:
@@ -10433,21 +10930,75 @@ class AITableGrid extends AITableGridBase {
10433
10930
  }
10434
10931
  return;
10435
10932
  }
10436
- this.aiTableGridSelectionService.clearDrag();
10933
+ this.setDragState({
10934
+ type: DragType.none,
10935
+ sourceIds: new Set()
10936
+ });
10937
+ }
10938
+ setDragState(config) {
10939
+ this.aiTable.dragState.set(config);
10940
+ }
10941
+ scrollViewToCell(position, startCell, endCell, coordinate, horizontalBarRef, verticalBarRef) {
10942
+ const [, startFieldId] = startCell;
10943
+ const [endRecordId, endFieldId] = endCell;
10944
+ const startColIndex = this.aiTable.context.visibleColumnsIndexMap().get(startFieldId);
10945
+ const endRowIndex = this.aiTable.context.visibleRowsIndexMap().get(endRecordId);
10946
+ const endColIndex = this.aiTable.context.visibleColumnsIndexMap().get(endFieldId);
10947
+ const isSelectionOnlyOnFrozenColumn = startColIndex === 0 && endColIndex === 0;
10948
+ const endCellTop = coordinate.getRowOffset(endRowIndex);
10949
+ const endCellLeft = coordinate.getColumnOffset(endColIndex);
10950
+ const scrollState = this.aiTable.context.scrollState();
10951
+ const gridData = this.aiTable.gridData();
10952
+ const containerRect = coordinate.container.getBoundingClientRect();
10953
+ this.scrollControllerService.scroll({
10954
+ container: containerRect,
10955
+ target: position,
10956
+ direction: isSelectionOnlyOnFrozenColumn ? 'vertical' : 'both',
10957
+ scrollableElement: {
10958
+ horizontalElement: horizontalBarRef?.nativeElement,
10959
+ verticalElement: verticalBarRef?.nativeElement
10960
+ },
10961
+ frozenArea: {
10962
+ top: AI_TABLE_FIELD_HEAD_HEIGHT,
10963
+ left: coordinate.getColumnWidth(0) + this.aiTable.context.rowHeadWidth(),
10964
+ bottom: containerRect.height - AI_TABLE_SCROLL_BAR_SIZE,
10965
+ right: containerRect.width - AI_TABLE_SCROLL_BAR_SIZE
10966
+ },
10967
+ edgeThreshold: {
10968
+ left: AI_TABLE_AUTO_SCROLL_LEFT_THRESHOLD,
10969
+ top: AI_TABLE_AUTO_SCROLL_TOP_THRESHOLD,
10970
+ right: AI_TABLE_SCROLL_BAR_SIZE + AI_TABLE_AUTO_SCROLL_RIGHT_THRESHOLD,
10971
+ bottom: AI_TABLE_AUTO_SCROLL_BOTTOM_THRESHOLD
10972
+ },
10973
+ onScrollChange: (position, isAutoScrolling) => {
10974
+ if (isAutoScrolling) {
10975
+ const scrollLeft = position.x - scrollState.scrollLeft;
10976
+ const scrollTop = position.y - scrollState.scrollTop;
10977
+ const nextCellIndex = coordinate.getColumnStartIndex(endCellLeft + scrollLeft);
10978
+ const nextRowIndex = coordinate.getRowStartIndex(endCellTop + scrollTop);
10979
+ // 向左滚动,单元格向后退一格,防止选区进入冻结列
10980
+ const nextField = gridData.fields[isSelectionOnlyOnFrozenColumn || scrollLeft > 0 ? nextCellIndex : nextCellIndex + 1];
10981
+ const nextRecord = gridData.records[nextRowIndex];
10982
+ if (nextField && nextRecord) {
10983
+ this.aiTableGridSelectionService.selectCells([startCell[0], nextField._id], [nextRecord._id, startCell[1]]);
10984
+ }
10985
+ }
10986
+ }
10987
+ });
10437
10988
  }
10438
10989
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableGrid, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
10439
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableGrid, isStandalone: true, selector: "ai-table-grid", host: { classAttribute: "ai-table-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "verticalBarRef", first: true, predicate: ["verticalBar"], descendants: true, isSignal: true }, { propertyName: "horizontalBarRef", first: true, predicate: ["horizontalBar"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div #container class=\"ai-table-grid-view\">\n @if (hasContainerRect()) {\n <ai-table-renderer\n [config]=\"rendererConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n (koMouseleave)=\"stageMouseleave($event)\"\n >\n @if (domToolTips().length > 0) {\n <div\n class=\"ai-table-left-background-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n @for (domToolTip of domToolTips(); track trackBy(idx, domToolTip); let idx = $index) {\n <div\n class=\"ai-table-left-background\"\n [thyTooltip]=\"'\u672C\u8BB0\u5F55\u5DF2\u88AB\u7B5B\u9009\u8FC7\u6EE4\uFF0C\u70B9\u51FB\u8BE5\u8BB0\u5F55\u4EE5\u5916\u4F4D\u7F6E\u5C06\u88AB\u9690\u85CF'\"\n [style.--scroll-top.px]=\"domToolTip.top\"\n >\n <thy-icon styxI18nTracking class=\"text-white\" thyIconName=\"filter-line\"></thy-icon>\n </div>\n }\n </div>\n }\n <div #horizontalBar class=\"ai-table-horizontal-scroll-bar-wrapper\" [style.width.px]=\"containerRect().width\">\n <div class=\"ai-table-scroll-bar-inner\" [style.width.px]=\"scrollbarWidth()\"></div>\n </div>\n <div\n #verticalBar\n class=\"ai-table-vertical-scroll-bar-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n <div class=\"ai-table-scroll-bar-inner\" [style.height.px]=\"scrollTotalHeight()\"></div>\n </div>\n </ai-table-renderer>\n }\n <ai-table-drag (dragEnd)=\"dragEnd($event)\"></ai-table-drag>\n</div>\n", dependencies: [{ kind: "component", type: AITableRenderer, selector: "ai-table-renderer", inputs: ["config"], outputs: ["koMousemove", "koMousedown", "koMouseup", "koContextmenu", "koWheel", "koClick", "koDblclick", "koMouseleave"] }, { kind: "component", type: AITableDragComponent, selector: "ai-table-drag", outputs: ["dragEnd"] }, { kind: "directive", type: ThyTooltipDirective, selector: "[thyTooltip],[thy-tooltip]", inputs: ["thyTooltip", "thyTooltipPlacement", "thyTooltipClass", "thyTooltipShowDelay", "thyTooltipHideDelay", "thyTooltipTrigger", "thyTooltipDisabled", "thyTooltipTemplateContext", "thyTooltipOffset", "thyTooltipPin"], exportAs: ["thyTooltip"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
10990
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AITableGrid, isStandalone: true, selector: "ai-table-grid", host: { classAttribute: "ai-table-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService, AITableScrollControllerService], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "verticalBarRef", first: true, predicate: ["verticalBar"], descendants: true, isSignal: true }, { propertyName: "horizontalBarRef", first: true, predicate: ["horizontalBar"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div #container class=\"ai-table-grid-view\">\n @if (hasContainerRect()) {\n <ai-table-renderer\n [config]=\"rendererConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n (koMouseleave)=\"stageMouseleave($event)\"\n >\n @if (domToolTips().length > 0) {\n <div\n class=\"ai-table-left-background-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n @for (domToolTip of domToolTips(); track trackBy(idx, domToolTip); let idx = $index) {\n <div\n class=\"ai-table-left-background\"\n [thyTooltip]=\"i18nTexts().rowAddFilterTooltip\"\n [style.--scroll-top.px]=\"domToolTip.top\"\n >\n <thy-icon class=\"text-white\" thyIconName=\"filter-line\"></thy-icon>\n </div>\n }\n </div>\n }\n <div #horizontalBar class=\"ai-table-horizontal-scroll-bar-wrapper\" [style.width.px]=\"containerRect().width\">\n <div class=\"ai-table-scroll-bar-inner\" [style.width.px]=\"scrollbarWidth()\"></div>\n </div>\n <div\n #verticalBar\n class=\"ai-table-vertical-scroll-bar-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n <div class=\"ai-table-scroll-bar-inner\" [style.height.px]=\"scrollTotalHeight()\"></div>\n </div>\n </ai-table-renderer>\n }\n <ai-table-drag [horizontalBar]=\"horizontalBarRef()\" [verticalBar]=\"verticalBarRef()\" (dragEnd)=\"dragEnd($event)\"></ai-table-drag>\n</div>\n", dependencies: [{ kind: "component", type: AITableRenderer, selector: "ai-table-renderer", inputs: ["config"], outputs: ["koMousemove", "koMousedown", "koMouseup", "koContextmenu", "koWheel", "koClick", "koDblclick", "koMouseleave"] }, { kind: "component", type: AITableDragComponent, selector: "ai-table-drag", inputs: ["horizontalBar", "verticalBar"], outputs: ["dragEnd"] }, { kind: "directive", type: ThyTooltipDirective, selector: "[thyTooltip],[thy-tooltip]", inputs: ["thyTooltip", "thyTooltipPlacement", "thyTooltipClass", "thyTooltipShowDelay", "thyTooltipHideDelay", "thyTooltipTrigger", "thyTooltipDisabled", "thyTooltipTemplateContext", "thyTooltipOffset", "thyTooltipPin"], exportAs: ["thyTooltip"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
10440
10991
  }
10441
10992
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AITableGrid, decorators: [{
10442
10993
  type: Component,
10443
10994
  args: [{ selector: 'ai-table-grid', changeDetection: ChangeDetectionStrategy.OnPush, host: {
10444
10995
  class: 'ai-table-grid'
10445
- }, imports: [AITableRenderer, AITableDragComponent, ThyTooltipDirective, ThyIcon], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div #container class=\"ai-table-grid-view\">\n @if (hasContainerRect()) {\n <ai-table-renderer\n [config]=\"rendererConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n (koMouseleave)=\"stageMouseleave($event)\"\n >\n @if (domToolTips().length > 0) {\n <div\n class=\"ai-table-left-background-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n @for (domToolTip of domToolTips(); track trackBy(idx, domToolTip); let idx = $index) {\n <div\n class=\"ai-table-left-background\"\n [thyTooltip]=\"'\u672C\u8BB0\u5F55\u5DF2\u88AB\u7B5B\u9009\u8FC7\u6EE4\uFF0C\u70B9\u51FB\u8BE5\u8BB0\u5F55\u4EE5\u5916\u4F4D\u7F6E\u5C06\u88AB\u9690\u85CF'\"\n [style.--scroll-top.px]=\"domToolTip.top\"\n >\n <thy-icon styxI18nTracking class=\"text-white\" thyIconName=\"filter-line\"></thy-icon>\n </div>\n }\n </div>\n }\n <div #horizontalBar class=\"ai-table-horizontal-scroll-bar-wrapper\" [style.width.px]=\"containerRect().width\">\n <div class=\"ai-table-scroll-bar-inner\" [style.width.px]=\"scrollbarWidth()\"></div>\n </div>\n <div\n #verticalBar\n class=\"ai-table-vertical-scroll-bar-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n <div class=\"ai-table-scroll-bar-inner\" [style.height.px]=\"scrollTotalHeight()\"></div>\n </div>\n </ai-table-renderer>\n }\n <ai-table-drag (dragEnd)=\"dragEnd($event)\"></ai-table-drag>\n</div>\n" }]
10996
+ }, imports: [AITableRenderer, AITableDragComponent, ThyTooltipDirective, ThyIcon], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService, AITableScrollControllerService], template: "<div #container class=\"ai-table-grid-view\">\n @if (hasContainerRect()) {\n <ai-table-renderer\n [config]=\"rendererConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n (koMouseleave)=\"stageMouseleave($event)\"\n >\n @if (domToolTips().length > 0) {\n <div\n class=\"ai-table-left-background-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n @for (domToolTip of domToolTips(); track trackBy(idx, domToolTip); let idx = $index) {\n <div\n class=\"ai-table-left-background\"\n [thyTooltip]=\"i18nTexts().rowAddFilterTooltip\"\n [style.--scroll-top.px]=\"domToolTip.top\"\n >\n <thy-icon class=\"text-white\" thyIconName=\"filter-line\"></thy-icon>\n </div>\n }\n </div>\n }\n <div #horizontalBar class=\"ai-table-horizontal-scroll-bar-wrapper\" [style.width.px]=\"containerRect().width\">\n <div class=\"ai-table-scroll-bar-inner\" [style.width.px]=\"scrollbarWidth()\"></div>\n </div>\n <div\n #verticalBar\n class=\"ai-table-vertical-scroll-bar-wrapper\"\n [style.height.px]=\"containerRect().height - fieldHeadHeight\"\n [style.top.px]=\"fieldHeadHeight\"\n >\n <div class=\"ai-table-scroll-bar-inner\" [style.height.px]=\"scrollTotalHeight()\"></div>\n </div>\n </ai-table-renderer>\n }\n <ai-table-drag [horizontalBar]=\"horizontalBarRef()\" [verticalBar]=\"verticalBarRef()\" (dragEnd)=\"dragEnd($event)\"></ai-table-drag>\n</div>\n" }]
10446
10997
  }], ctorParameters: () => [] });
10447
10998
 
10448
10999
  /**
10449
11000
  * Generated bundle index. Do not edit.
10450
11001
  */
10451
11002
 
10452
- export { AITable, AITableActionIcon, AITableAddField, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCellAttachment, AITableCellLink, AITableCellProgress, AITableCellRate, AITableCellRichText, AITableCells, AITableCheckType, AITableColumnHeads, AITableContextMenu, AITableDomGrid, AITableFieldHead, AITableFieldIcon, AITableFieldIsSameOptionPipe, AITableFieldSetting, AITableFrozenCells, AITableFrozenColumnHeads, AITableFrozenPlaceholderCells, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridI18nKey, AITableGridSelectionService, AITableHoverRowHeads, AITableIcon, AITableMemberType, AITableMouseDownType, AITableOtherRows, AITablePlaceholderCells, AITableQueries, AITableRenderer, AITableRowType, AITableSelectAllState, AITableTextComponent, 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_EDIT, 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_POINTER_HEIGHT, AI_TABLE_PROGRESS_BAR_POINTER_WIDTH, AI_TABLE_PROGRESS_BAR_RADIUS, AI_TABLE_PROGRESS_TEXT_WIDTH, AI_TABLE_RATE_MAX, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_DRAG, AI_TABLE_ROW_DRAG_ICON_WIDTH, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_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, AttachmentField, AttachmentPath, CellDrawer, Check, Colors, ColumnCalendarFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnRichTextFilledPath, 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, DateField, DepartmentOutlinedPath, Drawer, EditPath, FONT_SIZE_SM, FieldModelMap, GRID_CELL_EDITOR_MAP, HoverCellComponent, IconPathMap, IsSelectRecordPipe, KO_CONTAINER_TOKEN, KoComponent, KoContainer, KoShape, KoShapeTypes, KoStage, LinkCellEditorComponent, LinkField, MIN_COLUMN_WIDTH, MemberField, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, NumberField, ProgressField, RateField, RendererContext, RichTextField, RowDragPath, RowHeight, SelectCellEditorComponent, SelectField, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextField, TextMeasure, Unchecked, UserPipe, WebOutlinedPath, aiTableFragmentAttribute, applyNodeProps, buildClipboardData, buildGridData, buildGridLinearRows, castToString, cellDrawer, clearCells, compareNumber, compareOption, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, createListener, drawer, extractLinkUrl, extractText, generateNewName, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getDefaultFieldValue, getDefaultI18nTextByKey, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getFieldOptions, getFieldValue, getFileThumbnailSvgString, getHoverCell, getHoverEditorBoxOffset, getHoverEditorSpace, getI18nTextByKey, getMousePosition, getName, getPlaceHolderCellsConfigs, getSystemFieldValue, getTargetName, getTextWidth, getVisibleRangeInfo, graphemeSplitter, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isActiveCell, isArrayField, isCellMatchKeywords, isClipboardReadSupported, isClipboardReadTextSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isDateFiled, isEmptyOrNot, isMac, isMeetFilter, isNumberFiled, isSameFieldOption, isSelectedField, isSystemField, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, processPastedValueForSelect, readFromClipboard, scrollMax, setMouseStyle, shortIdCreator, shortIdsCreator, stringInclude, textDataCache, toAttachmentFieldValue, toDateFieldValue, toLinkFieldValue, toMemberFieldValue, toNumberFieldValue, toProgressFieldValue, toRateFieldValue, toRichTextFieldValue, toSelectFieldValue, toTextFieldValue, transformCellValue, updatePicture, writeToAITable, writeToClipboard, zhIntlCollator };
11003
+ export { AITable, AITableActionIcon, AITableAddField, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCellAttachment, AITableCellLink, AITableCellProgress, AITableCellRate, AITableCellRichText, AITableCells, AITableCheckType, AITableColumnHeads, AITableContextMenu, AITableDomGrid, AITableFieldHead, AITableFieldIcon, AITableFieldIsSameOptionPipe, AITableFieldSetting, AITableFrozenCells, AITableFrozenColumnHeads, AITableFrozenPlaceholderCells, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridI18nKey, AITableGridSelectionService, AITableHoverRowHeads, AITableIcon, AITableMemberType, AITableMouseDownType, AITableOtherRows, AITablePlaceholderCells, AITableQueries, AITableRenderer, AITableRowType, AITableSelectAllState, AITableTextComponent, AI_TABLE_ACTION_COMMON_RADIUS, AI_TABLE_ACTION_COMMON_RIGHT_PADDING, AI_TABLE_ACTION_COMMON_SIZE, AI_TABLE_AUTO_SCROLL_BOTTOM_THRESHOLD, AI_TABLE_AUTO_SCROLL_LEFT_THRESHOLD, AI_TABLE_AUTO_SCROLL_RIGHT_THRESHOLD, AI_TABLE_AUTO_SCROLL_TOP_THRESHOLD, AI_TABLE_BLANK, AI_TABLE_CELL, AI_TABLE_CELL_ACTIVE_BORDER_WIDTH, AI_TABLE_CELL_ADD_ITEM_BUTTON_SIZE, AI_TABLE_CELL_ATTACHMENT_ADD, AI_TABLE_CELL_ATTACHMENT_FILE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EDIT, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, AI_TABLE_CELL_FIELD_ITEM_HEIGHT, AI_TABLE_CELL_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_POINTER_HEIGHT, AI_TABLE_PROGRESS_BAR_POINTER_WIDTH, AI_TABLE_PROGRESS_BAR_RADIUS, AI_TABLE_PROGRESS_TEXT_WIDTH, AI_TABLE_RATE_MAX, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_DRAG, AI_TABLE_ROW_DRAG_ICON_WIDTH, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_HEIGHT, AI_TABLE_ROW_SELECT_CHECKBOX, AI_TABLE_SCROLL_BAR_PADDING, AI_TABLE_SCROLL_BAR_SIZE, AI_TABLE_TAG_FONT_SIZE, AI_TABLE_TAG_PADDING, AI_TABLE_TEXT_GAP, AbstractEditCellEditor, AddOutlinedPath, AttachmentField, AttachmentPath, CellDrawer, Check, Colors, ColumnCalendarFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnRichTextFilledPath, 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, DateField, DepartmentOutlinedPath, Drawer, EditPath, FONT_SIZE_SM, FieldModelMap, GRID_CELL_EDITOR_MAP, HoverCellComponent, IconPathMap, IsSelectRecordPipe, KO_CONTAINER_TOKEN, KoComponent, KoContainer, KoShape, KoShapeTypes, KoStage, LinkCellEditorComponent, LinkField, MIN_COLUMN_WIDTH, MemberField, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, NumberField, ProgressField, RateField, RendererContext, RichTextField, RowDragPath, RowHeight, SelectCellEditorComponent, SelectField, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextField, TextMeasure, Unchecked, UserPipe, WebOutlinedPath, aiTableFragmentAttribute, aiTableImageConfigToKonvaConfig, aiTableRectConfigToKonvaConfig, aiTableTextConfigToKonvaConfig, applyNodeProps, buildClipboardData, buildGridData, buildGridLinearRows, castToString, cellDrawer, clearCells, compareNumber, compareOption, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, createListener, defaultFieldOptions, drawer, extractLinkUrl, extractText, generateNewName, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getDefaultFieldValue, getDefaultI18nTextByKey, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getFieldOptionMap, getFieldOptions, getFieldValue, getFileThumbnailSvgString, getHoverCell, getHoverEditorBoxOffset, getHoverEditorSpace, getI18nTextByKey, getMousePosition, getName, getPlaceHolderCellsConfigs, getSystemFieldValue, getTargetName, getTextWidth, getVisibleRangeInfo, graphemeSplitter, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isActiveCell, isArrayField, isCellMatchKeywords, isClipboardReadSupported, isClipboardReadTextSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isDateFiled, isEmptyOrNot, isMac, isMeetFilter, isNumberFiled, isSameFieldOption, isSelectedField, isSystemField, isVirtualKey, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, processPastedValueForSelect, readFromClipboard, scrollMax, setMouseStyle, shortIdCreator, shortIdsCreator, stringInclude, textDataCache, toAttachmentFieldValue, toDateFieldValue, toLinkFieldValue, toMemberFieldValue, toNumberFieldValue, toProgressFieldValue, toRateFieldValue, toRichTextFieldValue, toSelectFieldValue, toTextFieldValue, transformCellValue, updatePicture, writeToAITable, writeToClipboard, zhIntlCollator };
10453
11004
  //# sourceMappingURL=ai-table-grid.mjs.map