@ai-table/grid 0.0.35 → 0.0.37

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 (53) hide show
  1. package/esm2022/components/cell-editors/date/date-editor.component.mjs +3 -3
  2. package/esm2022/components/cell-editors/link/link-editor.component.mjs +3 -3
  3. package/esm2022/components/cell-editors/select/select-editor.component.mjs +3 -3
  4. package/esm2022/core/constants/field.mjs +9 -9
  5. package/esm2022/renderer/components/cells/cells.mjs +6 -0
  6. package/esm2022/renderer/components/cells/index.mjs +2 -0
  7. package/esm2022/renderer/components/cells/link.component.mjs +90 -0
  8. package/esm2022/renderer/components/field-head.component.mjs +2 -2
  9. package/esm2022/renderer/components/hover-cell.component.mjs +103 -0
  10. package/esm2022/renderer/components/index.mjs +2 -1
  11. package/esm2022/renderer/components/text.component.mjs +27 -5
  12. package/esm2022/renderer/creations/create-cells.mjs +9 -3
  13. package/esm2022/renderer/drawers/cell-drawer.mjs +22 -6
  14. package/esm2022/renderer/interfaces/hover-cell.mjs +4 -0
  15. package/esm2022/renderer/interfaces/index.mjs +2 -0
  16. package/esm2022/renderer/renderer.component.mjs +8 -4
  17. package/esm2022/services/selection.service.mjs +8 -7
  18. package/esm2022/types/cell.mjs +1 -1
  19. package/esm2022/types/component-config.mjs +1 -1
  20. package/esm2022/utils/get-placeholder-cells.mjs +5 -5
  21. package/esm2022/utils/hover-cell.mjs +32 -0
  22. package/esm2022/utils/index.mjs +2 -1
  23. package/fesm2022/ai-table-grid.mjs +1219 -961
  24. package/fesm2022/ai-table-grid.mjs.map +1 -1
  25. package/package.json +1 -1
  26. package/renderer/components/cells/cells.d.ts +5 -0
  27. package/renderer/components/cells/cells.d.ts.map +1 -0
  28. package/renderer/components/cells/index.d.ts +2 -0
  29. package/renderer/components/cells/index.d.ts.map +1 -0
  30. package/renderer/components/cells/link.component.d.ts +23 -0
  31. package/renderer/components/cells/link.component.d.ts.map +1 -0
  32. package/renderer/components/hover-cell.component.d.ts +23 -0
  33. package/renderer/components/hover-cell.component.d.ts.map +1 -0
  34. package/renderer/components/index.d.ts +1 -0
  35. package/renderer/components/index.d.ts.map +1 -1
  36. package/renderer/components/text.component.d.ts +8 -93
  37. package/renderer/components/text.component.d.ts.map +1 -1
  38. package/renderer/creations/create-cells.d.ts +2 -0
  39. package/renderer/creations/create-cells.d.ts.map +1 -1
  40. package/renderer/drawers/cell-drawer.d.ts.map +1 -1
  41. package/renderer/interfaces/hover-cell.d.ts +8 -0
  42. package/renderer/interfaces/hover-cell.d.ts.map +1 -0
  43. package/renderer/interfaces/index.d.ts +2 -0
  44. package/renderer/interfaces/index.d.ts.map +1 -0
  45. package/renderer/renderer.component.d.ts.map +1 -1
  46. package/types/cell.d.ts +1 -0
  47. package/types/cell.d.ts.map +1 -1
  48. package/types/component-config.d.ts +10 -0
  49. package/types/component-config.d.ts.map +1 -1
  50. package/utils/hover-cell.d.ts +8 -0
  51. package/utils/hover-cell.d.ts.map +1 -0
  52. package/utils/index.d.ts +1 -0
  53. package/utils/index.d.ts.map +1 -1
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, computed, output, inject, ElementRef, Component, ChangeDetectionStrategy, Input, EventEmitter, Output, ChangeDetectorRef, ViewChild, HostListener, Pipe, input, Renderer2, model, booleanAttribute, Injectable, DestroyRef, NgZone, InjectionToken, effect, ViewContainerRef, viewChild, afterNextRender, untracked } from '@angular/core';
2
+ import { signal, computed, output, inject, ElementRef, Component, ChangeDetectionStrategy, Input, EventEmitter, Output, ChangeDetectorRef, ViewChild, HostListener, Pipe, input, Renderer2, model, booleanAttribute, Injectable, InjectionToken, effect, DestroyRef, NgZone, ViewContainerRef, viewChild, afterNextRender, untracked } from '@angular/core';
3
3
  import * as i1$1 from 'ngx-tethys/popover';
4
4
  import { ThyPopoverRef, ThyPopover, ThyPopoverModule } from 'ngx-tethys/popover';
5
5
  import ObjectID from 'bson-objectid';
@@ -47,6 +47,7 @@ import { fromUnixTime, subDays } from 'date-fns';
47
47
  import Konva from 'konva';
48
48
  import { Shape } from 'konva/lib/Shape';
49
49
  import { Sprite } from 'konva/lib/shapes/Sprite';
50
+ import GraphemeSplitter from 'grapheme-splitter';
50
51
  import { Stage } from 'konva/lib/Stage';
51
52
  import { FastLayer } from 'konva/lib/FastLayer';
52
53
  import { Group } from 'konva/lib/Group';
@@ -67,7 +68,6 @@ import { Text } from 'konva/lib/shapes/Text';
67
68
  import { TextPath } from 'konva/lib/shapes/TextPath';
68
69
  import { Transformer } from 'konva/lib/shapes/Transformer';
69
70
  import { Wedge } from 'konva/lib/shapes/Wedge';
70
- import GraphemeSplitter from 'grapheme-splitter';
71
71
 
72
72
  const Colors = {
73
73
  primary: '#6698FF',
@@ -200,14 +200,14 @@ const FieldOptions = [
200
200
  type: AITableFieldType.text,
201
201
  name: '单行文本',
202
202
  icon: 'font',
203
- width: 200
203
+ width: 300
204
204
  },
205
205
  // 多行文本
206
206
  {
207
207
  type: AITableFieldType.select,
208
208
  name: '单选',
209
209
  icon: 'check-circle',
210
- width: 200
210
+ width: 160
211
211
  },
212
212
  {
213
213
  type: AITableFieldType.select,
@@ -222,7 +222,7 @@ const FieldOptions = [
222
222
  type: AITableFieldType.number,
223
223
  name: '数字',
224
224
  icon: 'hashtag',
225
- width: 200
225
+ width: 140
226
226
  },
227
227
  {
228
228
  type: AITableFieldType.date,
@@ -234,7 +234,7 @@ const FieldOptions = [
234
234
  type: AITableFieldType.member,
235
235
  name: '单个成员',
236
236
  icon: 'user',
237
- width: 200
237
+ width: 160
238
238
  },
239
239
  {
240
240
  type: AITableFieldType.member,
@@ -257,19 +257,19 @@ const FieldOptions = [
257
257
  type: AITableFieldType.rate,
258
258
  name: '评分',
259
259
  icon: 'star-circle',
260
- width: 200
260
+ width: 160
261
261
  },
262
262
  {
263
263
  type: AITableFieldType.link,
264
264
  name: '链接',
265
265
  icon: 'link-insert',
266
- width: 300
266
+ width: 200
267
267
  },
268
268
  {
269
269
  type: AITableFieldType.createdBy,
270
270
  name: '创建人',
271
271
  icon: 'user',
272
- width: 200
272
+ width: 160
273
273
  },
274
274
  {
275
275
  type: AITableFieldType.createdAt,
@@ -281,7 +281,7 @@ const FieldOptions = [
281
281
  type: AITableFieldType.updatedBy,
282
282
  name: '更新人',
283
283
  icon: 'user',
284
- width: 200
284
+ width: 160
285
285
  },
286
286
  {
287
287
  type: AITableFieldType.updatedAt,
@@ -917,7 +917,7 @@ class DateCellEditorComponent extends AbstractEditCellEditor {
917
917
  <thy-date-picker
918
918
  class="h-100"
919
919
  thyTimestampPrecision="seconds"
920
- thyPlaceHolder="选择时间"
920
+ thyPlaceHolder="选择日期"
921
921
  [ngModel]="modelValue.timestamp"
922
922
  (ngModelChange)="updateValue($event)"
923
923
  (thyOpenChange)="thyOpenChange($event)"
@@ -939,7 +939,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
939
939
  <thy-date-picker
940
940
  class="h-100"
941
941
  thyTimestampPrecision="seconds"
942
- thyPlaceHolder="选择时间"
942
+ thyPlaceHolder="选择日期"
943
943
  [ngModel]="modelValue.timestamp"
944
944
  (ngModelChange)="updateValue($event)"
945
945
  (thyOpenChange)="thyOpenChange($event)"
@@ -1056,8 +1056,8 @@ class LinkCellEditorComponent extends AbstractEditCellEditor {
1056
1056
  ngOnInit() {
1057
1057
  super.ngOnInit();
1058
1058
  this.originValue = this.modelValue;
1059
- this.text = this.modelValue.text ?? '';
1060
- this.url = this.modelValue.url ?? '';
1059
+ this.text = this.modelValue?.text ?? '';
1060
+ this.url = this.modelValue?.url ?? '';
1061
1061
  }
1062
1062
  updateValue() {
1063
1063
  if (!this.isValidLink({ text: this.text, url: this.url ?? '' })) {
@@ -1399,7 +1399,7 @@ class SelectCellEditorComponent extends AbstractEditCellEditor {
1399
1399
  }
1400
1400
  }
1401
1401
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectCellEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1402
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SelectCellEditorComponent, isStandalone: true, selector: "select-cell-editor", host: { classAttribute: "d-block h-100 select-cell-editor" }, usesInheritance: true, ngImport: i0, template: "<thy-select\n [(ngModel)]=\"modelValue\"\n [thyAutoExpand]=\"true\"\n [thyAllowClear]=\"true\"\n [thyPreset]=\"preset()\"\n [thyMode]=\"field().settings.is_multiple ? 'multiple' : ''\"\n (thyOnExpandStatusChange)=\"updateValue($event)\"\n>\n <ng-template #selectedDisplay let-option>\n <select-option [field]=\"field()\" [displayOption]=\"option\"></select-option>\n </ng-template>\n @for (option of selectOptions(); track option._id) {\n <thy-option [thyValue]=\"option._id\" [thyRawValue]=\"option\" [thyShowOptionCustom]=\"true\" [thyLabelText]=\"option.text\">\n <select-option [field]=\"field()\" [displayOption]=\"option\"></select-option>\n </thy-option>\n }\n</thy-select>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ThySelect, selector: "thy-select,thy-custom-select", inputs: ["thyDropdownWidthMode", "thyShowSearch", "thyPlaceHolder", "thyServerSearch", "thyLoadState", "thyAutoActiveFirstItem", "thyMode", "thySize", "thyEmptyStateText", "thyEmptySearchMessageText", "thyEnableScrollLoad", "thyAllowClear", "thyDisabled", "thySortComparator", "thyFooterTemplate", "thyPlacement", "thyOrigin", "thyFooterClass", "thyAutoExpand", "thyHasBackdrop", "thyMaxTagCount", "thyBorderless", "thyOptions", "thyPreset"], outputs: ["thyOnSearch", "thyOnScrollToBottom", "thyOnExpandStatusChange"], exportAs: ["thySelect"] }, { kind: "component", type: ThyOption, selector: "thy-option", inputs: ["thyValue", "thyRawValue", "thyLabelText", "thyShowOptionCustom", "thySearchKey", "thyDisabled"], outputs: ["selectionChange", "visibleChange"] }, { kind: "ngmodule", type: ThyTooltipModule }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "ngmodule", type: ThyEmptyModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1402
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SelectCellEditorComponent, isStandalone: true, selector: "select-cell-editor", host: { classAttribute: "d-block h-100 select-cell-editor" }, usesInheritance: true, ngImport: i0, template: "<thy-select\n [(ngModel)]=\"modelValue\"\n [thyAutoExpand]=\"true\"\n [thyAllowClear]=\"true\"\n [thyPlaceHolder]=\"''\"\n [thyPreset]=\"preset()\"\n [thyMode]=\"field().settings.is_multiple ? 'multiple' : ''\"\n (thyOnExpandStatusChange)=\"updateValue($event)\"\n>\n <ng-template #selectedDisplay let-option>\n <select-option [field]=\"field()\" [displayOption]=\"option\"></select-option>\n </ng-template>\n @for (option of selectOptions(); track option._id) {\n <thy-option [thyValue]=\"option._id\" [thyRawValue]=\"option\" [thyShowOptionCustom]=\"true\" [thyLabelText]=\"option.text\">\n <select-option [field]=\"field()\" [displayOption]=\"option\"></select-option>\n </thy-option>\n }\n</thy-select>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ThySelect, selector: "thy-select,thy-custom-select", inputs: ["thyDropdownWidthMode", "thyShowSearch", "thyPlaceHolder", "thyServerSearch", "thyLoadState", "thyAutoActiveFirstItem", "thyMode", "thySize", "thyEmptyStateText", "thyEmptySearchMessageText", "thyEnableScrollLoad", "thyAllowClear", "thyDisabled", "thySortComparator", "thyFooterTemplate", "thyPlacement", "thyOrigin", "thyFooterClass", "thyAutoExpand", "thyHasBackdrop", "thyMaxTagCount", "thyBorderless", "thyOptions", "thyPreset"], outputs: ["thyOnSearch", "thyOnScrollToBottom", "thyOnExpandStatusChange"], exportAs: ["thySelect"] }, { kind: "component", type: ThyOption, selector: "thy-option", inputs: ["thyValue", "thyRawValue", "thyLabelText", "thyShowOptionCustom", "thySearchKey", "thyDisabled"], outputs: ["selectionChange", "visibleChange"] }, { kind: "ngmodule", type: ThyTooltipModule }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "ngmodule", type: ThyEmptyModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1403
1403
  }
1404
1404
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectCellEditorComponent, decorators: [{
1405
1405
  type: Component,
@@ -1418,7 +1418,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1418
1418
  SelectOptionPipe,
1419
1419
  SelectOptionComponent,
1420
1420
  ThyEmptyModule
1421
- ], template: "<thy-select\n [(ngModel)]=\"modelValue\"\n [thyAutoExpand]=\"true\"\n [thyAllowClear]=\"true\"\n [thyPreset]=\"preset()\"\n [thyMode]=\"field().settings.is_multiple ? 'multiple' : ''\"\n (thyOnExpandStatusChange)=\"updateValue($event)\"\n>\n <ng-template #selectedDisplay let-option>\n <select-option [field]=\"field()\" [displayOption]=\"option\"></select-option>\n </ng-template>\n @for (option of selectOptions(); track option._id) {\n <thy-option [thyValue]=\"option._id\" [thyRawValue]=\"option\" [thyShowOptionCustom]=\"true\" [thyLabelText]=\"option.text\">\n <select-option [field]=\"field()\" [displayOption]=\"option\"></select-option>\n </thy-option>\n }\n</thy-select>\n" }]
1421
+ ], template: "<thy-select\n [(ngModel)]=\"modelValue\"\n [thyAutoExpand]=\"true\"\n [thyAllowClear]=\"true\"\n [thyPlaceHolder]=\"''\"\n [thyPreset]=\"preset()\"\n [thyMode]=\"field().settings.is_multiple ? 'multiple' : ''\"\n (thyOnExpandStatusChange)=\"updateValue($event)\"\n>\n <ng-template #selectedDisplay let-option>\n <select-option [field]=\"field()\" [displayOption]=\"option\"></select-option>\n </ng-template>\n @for (option of selectOptions(); track option._id) {\n <thy-option [thyValue]=\"option._id\" [thyRawValue]=\"option\" [thyShowOptionCustom]=\"true\" [thyLabelText]=\"option.text\">\n <select-option [field]=\"field()\" [displayOption]=\"option\"></select-option>\n </thy-option>\n }\n</thy-select>\n" }]
1422
1422
  }], ctorParameters: () => [] });
1423
1423
 
1424
1424
  class TextCellEditorComponent extends AbstractEditCellEditor {
@@ -1663,18 +1663,18 @@ class AITableGridSelectionService {
1663
1663
  }
1664
1664
  selectCells(startCell, endCell) {
1665
1665
  const [startRecordId, startFieldId] = startCell;
1666
- const records = this.aiTable.records();
1667
- const fields = this.aiTable.fields();
1666
+ const records = this.aiTable.context.linearRows();
1667
+ const fields = AITable.getVisibleFields(this.aiTable);
1668
1668
  const selectedCells = new Set();
1669
1669
  if (!endCell) {
1670
1670
  selectedCells.add(`${startRecordId}:${startFieldId}`);
1671
1671
  }
1672
1672
  else {
1673
1673
  const [endRecordId, endFieldId] = endCell;
1674
- const startRowIndex = records.findIndex((record) => record._id === startRecordId);
1675
- const endRowIndex = records.findIndex((record) => record._id === endRecordId);
1676
- const startColIndex = fields.findIndex((field) => field._id === startFieldId);
1677
- const endColIndex = fields.findIndex((field) => field._id === endFieldId);
1674
+ const startRowIndex = this.aiTable.context.visibleRowsIndexMap().get(startRecordId);
1675
+ const endRowIndex = this.aiTable.context.visibleRowsIndexMap().get(endRecordId);
1676
+ const startColIndex = this.aiTable.context.visibleColumnsIndexMap().get(startFieldId);
1677
+ const endColIndex = this.aiTable.context.visibleColumnsIndexMap().get(endFieldId);
1678
1678
  const minRowIndex = Math.min(startRowIndex, endRowIndex);
1679
1679
  const maxRowIndex = Math.max(startRowIndex, endRowIndex);
1680
1680
  const minColIndex = Math.min(startColIndex, endColIndex);
@@ -2150,7 +2150,7 @@ function getPlaceHolderCellsConfigs(options) {
2150
2150
  return [];
2151
2151
  }
2152
2152
  // 当前列的 X 轴偏移量和列宽度
2153
- const x = coordinate.getColumnOffset(columnIndex) + AI_TABLE_OFFSET;
2153
+ const x = coordinate.getColumnOffset(columnIndex) + AI_TABLE_OFFSET * 2;
2154
2154
  const columnWidth = coordinate.getColumnWidth(columnIndex);
2155
2155
  for (let rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) {
2156
2156
  // 当前行索引是否超出总行数范围,超出则退出循环
@@ -2163,13 +2163,13 @@ function getPlaceHolderCellsConfigs(options) {
2163
2163
  continue;
2164
2164
  }
2165
2165
  // 当前行的 Y 轴偏移量,并根据列宽和列索引获取单元格的水平位置(宽度和偏移量)
2166
- const y = coordinate.getRowOffset(rowIndex) + AI_TABLE_OFFSET;
2166
+ const y = coordinate.getRowOffset(rowIndex) + AI_TABLE_OFFSET * 2;
2167
2167
  const { width, offset } = getCellHorizontalPosition({
2168
2168
  columnWidth,
2169
2169
  columnIndex,
2170
2170
  columnCount
2171
2171
  });
2172
- const height = rowHeight;
2172
+ const height = rowHeight - AI_TABLE_OFFSET * 4;
2173
2173
  configs.unshift({
2174
2174
  key: `placeholder-cell-${fieldId}-${recordId}`,
2175
2175
  name: generateTargetName({
@@ -2179,7 +2179,7 @@ function getPlaceHolderCellsConfigs(options) {
2179
2179
  }),
2180
2180
  x: x + offset,
2181
2181
  y,
2182
- width,
2182
+ width: width - AI_TABLE_OFFSET * 4,
2183
2183
  height,
2184
2184
  fill: Colors.transparent,
2185
2185
  strokeEnabled: false,
@@ -2922,613 +2922,190 @@ const isCellMatchKeywords = (aiTable, field, recordId, keywords, references) =>
2922
2922
  return keywords && cellFullText.length && cellFullText.some((text) => text.toLowerCase().includes(keywords.toLowerCase()));
2923
2923
  };
2924
2924
 
2925
- class AITableGridEventService {
2926
- constructor() {
2927
- this.dblClickEvent$ = new Subject();
2928
- this.mousedownEvent$ = new Subject();
2929
- this.mouseoverEvent$ = new Subject();
2930
- this.globalMouseoverEvent$ = new Subject();
2931
- this.globalMousedownEvent$ = new Subject();
2932
- this.destroyRef = inject(DestroyRef);
2933
- this.thyPopover = inject(ThyPopover);
2934
- }
2935
- initialize(aiTable, aiFieldRenderers) {
2936
- this.aiTable = aiTable;
2937
- this.aiFieldRenderers = aiFieldRenderers;
2925
+ function updatePicture(node) {
2926
+ const drawingNode = node.getLayer() || node.getStage();
2927
+ if (drawingNode) {
2928
+ drawingNode.batchDraw();
2938
2929
  }
2939
- registerEvents(element) {
2940
- fromEvent(element, 'dblclick', { passive: true })
2941
- .pipe(takeUntilDestroyed(this.destroyRef))
2942
- .subscribe((event) => {
2943
- this.dblClickEvent$.next(event);
2944
- });
2945
- fromEvent(element, 'mouseover', { passive: true })
2946
- .pipe(debounceTime(80), takeUntilDestroyed(this.destroyRef))
2947
- .subscribe((event) => {
2948
- this.mouseoverEvent$.next(event);
2949
- });
2950
- fromEvent(document, 'mouseover', { passive: true })
2951
- .pipe(takeUntilDestroyed(this.destroyRef))
2952
- .subscribe((event) => {
2953
- this.globalMouseoverEvent$.next(event);
2954
- });
2955
- fromEvent(element, 'mousedown', { passive: true })
2956
- .pipe(takeUntilDestroyed(this.destroyRef))
2957
- .subscribe((event) => {
2958
- this.mousedownEvent$.next(event);
2959
- });
2960
- fromEvent(document, 'mousedown', { passive: true })
2961
- .pipe(takeUntilDestroyed(this.destroyRef))
2962
- .subscribe((event) => {
2963
- this.globalMousedownEvent$.next(event);
2964
- });
2930
+ }
2931
+
2932
+ // adapted FROM: https://github.com/lavrton/react-konva/blob/master/src/react-konva-fiber.js
2933
+ function applyNodeProps(component, props = {}, oldProps = {}) {
2934
+ if ('id' in props) {
2935
+ const message = `You are using "id" attribute for Konva node. In some very rare cases it may produce bugs. Currently we recommend not to use it and use "name" attribute instead.`;
2936
+ console.warn(message);
2965
2937
  }
2966
- getEditorComponent(type) {
2967
- const filedRenderSchema = this.aiFieldRenderers && this.aiFieldRenderers[type];
2968
- if (filedRenderSchema && filedRenderSchema.editor) {
2969
- return filedRenderSchema.editor;
2938
+ const instance = component.getNode();
2939
+ const updatedProps = {};
2940
+ let hasUpdates = false;
2941
+ Object.keys(oldProps).forEach((key) => {
2942
+ const isEvent = key.slice(0, 2) === 'ko';
2943
+ const propChanged = oldProps[key] !== props[key];
2944
+ if (isEvent && propChanged) {
2945
+ let eventName = key.slice(2).toLowerCase();
2946
+ if (eventName.slice(0, 7) === 'content') {
2947
+ eventName = 'content' + eventName.slice(7, 8).toUpperCase() + eventName.slice(8);
2948
+ }
2949
+ instance.off(eventName, oldProps[key]);
2970
2950
  }
2971
- return GRID_CELL_EDITOR_MAP[type];
2972
- }
2973
- openEdit(cellDom) {
2974
- const { x, y, width, height } = cellDom.getBoundingClientRect();
2975
- const fieldId = cellDom.getAttribute('fieldId');
2976
- const recordId = cellDom.getAttribute('recordId');
2977
- const component = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
2978
- const ref = this.thyPopover.open(component, {
2979
- origin: cellDom,
2980
- originPosition: {
2981
- x: x - 1,
2982
- y: y + 1,
2983
- width: width + 2,
2984
- height: height + 2
2985
- },
2986
- width: width + 1 + 'px',
2987
- height: height + 2 + 'px',
2988
- placement: 'top',
2989
- offset: -(height + 4),
2990
- minWidth: width,
2991
- initialState: {
2992
- fieldId: fieldId,
2993
- recordId: recordId,
2994
- aiTable: this.aiTable
2995
- },
2996
- panelClass: 'grid-cell-editor',
2997
- outsideClosable: false,
2998
- hasBackdrop: false,
2999
- manualClosure: true,
3000
- animationDisabled: true,
3001
- autoAdaptive: true
3002
- });
3003
- return ref;
3004
- }
3005
- getOriginPosition(aiTable, options) {
3006
- const { container, coordinate, recordId, fieldId, isHoverEdit } = options;
3007
- const { scrollState } = aiTable.context;
3008
- const { rowHeight, columnCount } = coordinate;
3009
- const cell = [recordId, fieldId];
3010
- const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, cell);
3011
- const originX = coordinate.getColumnOffset(columnIndex);
3012
- const originY = coordinate.getRowOffset(rowIndex);
3013
- const columnWidth = coordinate.getColumnWidth(columnIndex);
3014
- const { width: originWidth, offset: originOffset } = getCellHorizontalPosition({
3015
- columnWidth,
3016
- columnIndex,
3017
- columnCount
3018
- });
3019
- const originRect = container.getBoundingClientRect();
3020
- const isFrozenColumn = AITable.isFrozenColumn(aiTable, columnIndex);
3021
- const scrollLeft = isFrozenColumn ? 0 : scrollState().scrollLeft;
3022
- const scrollTop = scrollState().scrollTop;
3023
- const originPosition = {
3024
- x: originX + originOffset - scrollLeft + originRect.x,
3025
- y: originY - scrollTop + originRect.y,
3026
- width: originWidth,
3027
- height: rowHeight
3028
- };
3029
- let x = originPosition.x + getEditorBoxOffset();
3030
- let y = originPosition.y + getEditorBoxOffset();
3031
- let width = getEditorSpace(originPosition.width);
3032
- let height = getEditorSpace(originPosition.height);
3033
- // hover 编辑组件无边框
3034
- if (isHoverEdit) {
3035
- x = originPosition.x + getHoverEditorBoxOffset();
3036
- y = originPosition.y + getHoverEditorBoxOffset();
3037
- width = getHoverEditorSpace(originPosition.width);
3038
- height = getHoverEditorSpace(originPosition.height);
2951
+ const toRemove = !Object.hasOwn(props, key);
2952
+ if (toRemove) {
2953
+ instance.setAttr(key, undefined);
3039
2954
  }
3040
- return {
3041
- ...originPosition,
3042
- x: x,
3043
- y: y,
3044
- width: width,
3045
- height: height
3046
- };
3047
- }
3048
- openCellEditor(aiTable, options) {
3049
- const { container, recordId, fieldId, isHoverEdit, references } = options;
3050
- const component = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
3051
- const offsetOriginPosition = this.getOriginPosition(aiTable, options);
3052
- this.cellEditorPopoverRef = this.thyPopover.open(component, {
3053
- origin: container,
3054
- originPosition: offsetOriginPosition,
3055
- width: offsetOriginPosition.width + 'px',
3056
- height: offsetOriginPosition.height + 'px',
3057
- minWidth: offsetOriginPosition.width + 'px',
3058
- placement: 'bottom',
3059
- offset: -offsetOriginPosition.height,
3060
- initialState: {
3061
- fieldId: fieldId,
3062
- recordId: recordId,
3063
- references,
3064
- aiTable: aiTable
3065
- },
3066
- panelClass: 'grid-cell-editor',
3067
- outsideClosable: false,
3068
- hasBackdrop: false,
3069
- manualClosure: true,
3070
- animationDisabled: true,
3071
- autoAdaptive: true
3072
- });
3073
- if (this.cellEditorPopoverRef) {
3074
- const wheelEvent = fromEvent(this.cellEditorPopoverRef.componentInstance.elementRef.nativeElement, 'wheel').subscribe((event) => {
3075
- const field = aiTable.fieldsMap()[fieldId];
3076
- if (field.type === AITableFieldType.text || field.type === AITableFieldType.richText) {
3077
- return;
3078
- }
3079
- event.preventDefault();
3080
- this.aiTable.context?.scrollAction({
3081
- deltaX: event.deltaX,
3082
- deltaY: event.deltaY,
3083
- shiftKey: event.shiftKey,
3084
- callback: () => {
3085
- const originPosition = this.getOriginPosition(aiTable, options);
3086
- const positionStrategy = this.cellEditorPopoverRef
3087
- .getOverlayRef()
3088
- .getConfig().positionStrategy;
3089
- positionStrategy.setOrigin(originPosition);
3090
- positionStrategy.apply();
3091
- }
2955
+ });
2956
+ Object.keys(props).forEach((key) => {
2957
+ const isEvent = key.slice(0, 2) === 'ko';
2958
+ const toAdd = oldProps[key] !== props[key];
2959
+ if (isEvent && toAdd) {
2960
+ let eventName = key.slice(2).toLowerCase();
2961
+ if (eventName.slice(0, 7) === 'content') {
2962
+ eventName = 'content' + eventName.slice(7, 8).toUpperCase() + eventName.slice(8);
2963
+ }
2964
+ if (props[key]) {
2965
+ instance.off(eventName);
2966
+ instance.on(eventName, (event) => {
2967
+ props[key]({
2968
+ angularComponent: component,
2969
+ event
2970
+ });
3092
2971
  });
3093
- });
3094
- this.cellEditorPopoverRef.afterClosed().subscribe(() => {
3095
- wheelEvent.unsubscribe();
3096
- this.cellEditorPopoverRef = null;
3097
- });
3098
- this.cellEditorPopoverRef.componentInstance.updateFieldValue.subscribe((value) => {
3099
- options.updateFieldValue(value);
3100
- });
2972
+ }
3101
2973
  }
3102
- return this.cellEditorPopoverRef;
3103
- }
3104
- closeCellEditor() {
3105
- if (this.cellEditorPopoverRef) {
3106
- this.cellEditorPopoverRef.close();
3107
- this.cellEditorPopoverRef = null;
2974
+ if (!isEvent && (props[key] !== oldProps[key] || props[key] !== instance.getAttr(key))) {
2975
+ hasUpdates = true;
2976
+ updatedProps[key] = props[key];
3108
2977
  }
2978
+ });
2979
+ if (hasUpdates) {
2980
+ instance.setAttrs(updatedProps);
2981
+ updatePicture(instance);
2982
+ let val;
2983
+ Object.keys(updatedProps).forEach((prop) => {
2984
+ val = updatedProps[prop];
2985
+ if (val instanceof Image && !val.complete) {
2986
+ const node = instance;
2987
+ val.addEventListener('load', function () {
2988
+ const layer = node.getLayer();
2989
+ if (layer) {
2990
+ layer.batchDraw();
2991
+ }
2992
+ });
2993
+ }
2994
+ });
3109
2995
  }
3110
- getCurrentEditCell() {
3111
- if (this.cellEditorPopoverRef) {
3112
- const recordId = this.cellEditorPopoverRef.componentInstance?.recordId;
3113
- const fieldId = this.cellEditorPopoverRef.componentInstance?.fieldId;
3114
- if (recordId && fieldId) {
3115
- return {
3116
- recordId,
3117
- fieldId
3118
- };
3119
- }
3120
- return null;
2996
+ }
2997
+
2998
+ function camelize(str) {
2999
+ return str
3000
+ .replace(/^\w|[A-Z]|\b\w/g, function (letter, index) {
3001
+ return index == 0 ? letter.toLowerCase() : letter.toUpperCase();
3002
+ })
3003
+ .replace(/\s+/g, '');
3004
+ }
3005
+ function capitalizeFirstLetter(string) {
3006
+ return string.charAt(0).toUpperCase() + string.slice(1);
3007
+ }
3008
+ function getName(componentTag) {
3009
+ return capitalizeFirstLetter(camelize(componentTag.slice(3).replace('-', ' ')));
3010
+ }
3011
+ function createListener(instance) {
3012
+ const output = {};
3013
+ [
3014
+ 'koMouseover',
3015
+ 'koMousemove',
3016
+ 'koMouseout',
3017
+ 'koMouseenter',
3018
+ 'koMouseleave',
3019
+ 'koMousedown',
3020
+ 'koMouseup',
3021
+ 'koWheel',
3022
+ 'koContextmenu',
3023
+ 'koClick',
3024
+ 'koDblclick',
3025
+ 'koTouchstart',
3026
+ 'koTouchmove',
3027
+ 'koTouchend',
3028
+ 'koTap',
3029
+ 'koDbltap',
3030
+ 'koDragstart',
3031
+ 'koDragmove',
3032
+ 'koDragend'
3033
+ ].forEach((eventName) => {
3034
+ const name = eventName;
3035
+ const eventEmitter = instance[name];
3036
+ if (eventEmitter.observed) {
3037
+ output[eventName] = eventEmitter.emit.bind(eventEmitter);
3121
3038
  }
3122
- return null;
3123
- }
3124
- openContextMenu(aiTable, options) {
3125
- const { origin, position, menuItems, targetName, viewContainerRef } = options;
3126
- const ref = this.thyPopover.open(AITableContextMenu, {
3127
- origin: origin,
3128
- originPosition: position,
3129
- placement: 'bottomLeft',
3130
- insideClosable: true,
3131
- viewContainerRef,
3132
- initialState: {
3133
- aiTable,
3134
- menuItems,
3135
- targetName,
3136
- position
3137
- }
3138
- });
3139
- return ref;
3140
- }
3141
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3142
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService }); }
3039
+ });
3040
+ return output;
3143
3041
  }
3144
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, decorators: [{
3145
- type: Injectable
3146
- }] });
3147
3042
 
3148
- class AITableGridBase {
3043
+ const KO_CONTAINER_TOKEN = new InjectionToken('KO_CONTAINER_TOKEN');
3044
+
3045
+ class KoShape {
3149
3046
  constructor() {
3150
- this.aiRecords = model.required();
3151
- this.aiFields = model.required();
3152
- this.aiContextMenuItems = input([]);
3153
- this.aiFieldConfig = input();
3154
- this.aiReadonly = input();
3155
- this.aiPlugins = input();
3156
- this.aiReferences = input.required();
3157
- this.aiBuildRenderDataFn = input();
3158
- this.aiKeywords = input();
3159
- this.AITableFieldType = AITableFieldType;
3160
- this.AITableSelectOptionStyle = AITableSelectOptionStyle;
3161
- this.isSelectedAll = computed(() => {
3162
- return this.aiTable.selection().selectedRecords.size === this.aiRecords().length;
3163
- });
3164
- this.aiTableInitialized = output();
3165
- this.aiAddRecord = output();
3166
- this.aiAddField = output();
3167
- this.aiUpdateFieldValue = output();
3168
- this.fieldMenus = computed(() => {
3169
- return this.aiFieldConfig()?.fieldMenus || [];
3170
- });
3171
- this.gridData = computed(() => {
3172
- if (this.aiBuildRenderDataFn && this.aiBuildRenderDataFn() && this.aiTable) {
3173
- return this.aiBuildRenderDataFn()(this.aiTable);
3047
+ this.config = input();
3048
+ this.koMouseover = new EventEmitter();
3049
+ this.koMousemove = new EventEmitter();
3050
+ this.koMouseout = new EventEmitter();
3051
+ this.koMouseenter = new EventEmitter();
3052
+ this.koMouseleave = new EventEmitter();
3053
+ this.koMousedown = new EventEmitter();
3054
+ this.koMouseup = new EventEmitter();
3055
+ this.koWheel = new EventEmitter();
3056
+ this.koContextmenu = new EventEmitter();
3057
+ this.koClick = new EventEmitter();
3058
+ this.koDblclick = new EventEmitter();
3059
+ this.koTouchstart = new EventEmitter();
3060
+ this.koTouchmove = new EventEmitter();
3061
+ this.koTouchend = new EventEmitter();
3062
+ this.koTap = new EventEmitter();
3063
+ this.koDbltap = new EventEmitter();
3064
+ this.koDragstart = new EventEmitter();
3065
+ this.koDragmove = new EventEmitter();
3066
+ this.koDragend = new EventEmitter();
3067
+ this.elementRef = inject((ElementRef));
3068
+ this.container = inject(KO_CONTAINER_TOKEN, { skipSelf: true });
3069
+ this.cacheProps = {};
3070
+ this.nameNode = getName(this.elementRef.nativeElement.localName);
3071
+ effect(() => {
3072
+ if (this.config()) {
3073
+ this.updateNode(this.config());
3174
3074
  }
3175
- return {
3176
- records: this.aiRecords(),
3177
- fields: this.aiFields()
3178
- };
3179
- });
3180
- this.ngZone = inject(NgZone);
3181
- this.elementRef = inject(ElementRef);
3182
- this.destroyRef = inject(DestroyRef);
3183
- this.aiTableGridFieldService = inject(AITableGridFieldService);
3184
- this.aiTableGridEventService = inject(AITableGridEventService);
3185
- this.aiTableGridSelectionService = inject(AITableGridSelectionService);
3186
- }
3187
- ngOnInit() {
3188
- this.initAITable();
3189
- this.initService();
3190
- }
3191
- initAITable() {
3192
- this.aiTable = createAITable(this.aiRecords, this.aiFields);
3193
- this.aiPlugins()?.forEach((plugin) => {
3194
- this.aiTable = plugin(this.aiTable);
3195
- });
3196
- this.aiTableInitialized.emit(this.aiTable);
3197
- }
3198
- initService() {
3199
- this.aiTableGridEventService.initialize(this.aiTable, this.aiFieldConfig()?.fieldRenderers);
3200
- this.aiTableGridSelectionService.initialize(this.aiTable);
3201
- this.aiTableGridEventService.registerEvents(this.elementRef.nativeElement);
3202
- this.aiTableGridFieldService.initAIFieldConfig(this.aiFieldConfig());
3203
- AI_TABLE_GRID_FIELD_SERVICE_MAP.set(this.aiTable, this.aiTableGridFieldService);
3204
- }
3205
- addRecord() {
3206
- const records = this.gridData().records;
3207
- const recordCount = records.length;
3208
- this.aiAddRecord.emit({
3209
- originId: recordCount > 0 ? records[records.length - 1]._id : ''
3210
3075
  });
3211
3076
  }
3212
- selectRecord(recordId) {
3213
- this.aiTableGridSelectionService.selectRecord(recordId);
3077
+ getNode() {
3078
+ return this._node;
3214
3079
  }
3215
- toggleSelectAll(checked) {
3216
- this.aiTableGridSelectionService.toggleSelectAll(checked);
3080
+ ngOnInit() {
3081
+ this.initKonva();
3217
3082
  }
3218
- addField(gridColumnBlank, position) {
3219
- const field = createDefaultField(this.aiTable, AITableFieldType.text);
3220
- const popoverRef = this.aiTableGridFieldService.editFieldProperty(this.aiTable, {
3221
- field,
3222
- isUpdate: false,
3223
- origin: gridColumnBlank,
3224
- position
3225
- });
3226
- if (popoverRef && !this.aiFieldConfig()?.fieldSettingComponent) {
3227
- popoverRef.componentInstance.addField.subscribe((defaultValue) => {
3228
- const fields = this.gridData().fields;
3229
- const fieldCount = fields.length;
3230
- this.aiAddField.emit({
3231
- originId: fieldCount > 0 ? fields[fields.length - 1]._id : '',
3232
- defaultValue
3233
- });
3234
- });
3083
+ initKonva() {
3084
+ if (!this._node) {
3085
+ this._node = new Shape();
3235
3086
  }
3236
- }
3237
- subscribeEvents() {
3238
- this.ngZone.runOutsideAngular(() => {
3239
- this.aiTableGridEventService.dblClickEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
3240
- this.dblClick(event);
3241
- });
3242
- this.aiTableGridEventService.mousedownEvent$
3243
- .pipe(mergeWith(this.aiTableGridEventService.globalMousedownEvent$), takeUntilDestroyed(this.destroyRef))
3244
- .subscribe((event) => {
3245
- this.aiTableGridSelectionService.updateSelect(event);
3246
- });
3247
- this.aiTableGridEventService.mouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
3248
- this.mouseoverHandle(event);
3249
- });
3250
- this.aiTableGridEventService.globalMouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
3251
- this.closeHoverCellEditor(event);
3252
- });
3253
- });
3254
- }
3255
- dblClick(event) {
3256
- const cellDom = event.target.closest('.grid-cell');
3257
- const type = cellDom && cellDom.getAttribute('type');
3258
- if (type && DBL_CLICK_EDIT_TYPE.includes(type)) {
3259
- this.aiTableGridEventService.openEdit(cellDom);
3087
+ if (this.nameNode === 'Shape') {
3088
+ this._node = new Shape();
3260
3089
  }
3261
- }
3262
- mouseoverHandle(event) {
3263
- if (this.mouseoverRef) {
3264
- this.mouseoverRef?.close();
3090
+ else if (this.nameNode === 'Sprite') {
3091
+ this._node = new Sprite(this.config());
3265
3092
  }
3266
- const cellDom = event.target.closest('.grid-cell');
3267
- const type = cellDom && cellDom.getAttribute('type');
3268
- if (type && MOUSEOVER_EDIT_TYPE.includes(type)) {
3269
- this.mouseoverRef = this.aiTableGridEventService.openEdit(cellDom);
3093
+ else {
3094
+ this._node = new Konva[this.nameNode](undefined);
3270
3095
  }
3271
- }
3272
- closeHoverCellEditor(e) {
3273
- if (this.mouseoverRef) {
3274
- const hasGrid = e.target && e.target.closest('.ai-table-grid');
3275
- const hasCellEditor = e.target && e.target.closest('.grid-cell-editor');
3276
- if (!hasGrid && !hasCellEditor) {
3277
- this.mouseoverRef.close();
3278
- }
3279
- }
3280
- }
3281
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3282
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableGridBase, isStandalone: true, selector: "ai-table-grid-base", inputs: { aiRecords: { classPropertyName: "aiRecords", publicName: "aiRecords", isSignal: true, isRequired: true, transformFunction: null }, aiFields: { classPropertyName: "aiFields", publicName: "aiFields", isSignal: true, isRequired: true, transformFunction: null }, aiContextMenuItems: { classPropertyName: "aiContextMenuItems", publicName: "aiContextMenuItems", isSignal: true, isRequired: false, transformFunction: null }, aiFieldConfig: { classPropertyName: "aiFieldConfig", publicName: "aiFieldConfig", isSignal: true, isRequired: false, transformFunction: null }, aiReadonly: { classPropertyName: "aiReadonly", publicName: "aiReadonly", isSignal: true, isRequired: false, transformFunction: null }, aiPlugins: { classPropertyName: "aiPlugins", publicName: "aiPlugins", isSignal: true, isRequired: false, transformFunction: null }, aiReferences: { classPropertyName: "aiReferences", publicName: "aiReferences", isSignal: true, isRequired: true, transformFunction: null }, aiBuildRenderDataFn: { classPropertyName: "aiBuildRenderDataFn", publicName: "aiBuildRenderDataFn", isSignal: true, isRequired: false, transformFunction: null }, aiKeywords: { classPropertyName: "aiKeywords", publicName: "aiKeywords", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiRecords: "aiRecordsChange", aiFields: "aiFieldsChange", aiTableInitialized: "aiTableInitialized", aiAddRecord: "aiAddRecord", aiAddField: "aiAddField", aiUpdateFieldValue: "aiUpdateFieldValue" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3283
- }
3284
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, decorators: [{
3285
- type: Component,
3286
- args: [{
3287
- selector: 'ai-table-grid-base',
3288
- template: '',
3289
- standalone: true,
3290
- changeDetection: ChangeDetectionStrategy.OnPush
3291
- }]
3292
- }] });
3293
-
3294
- class AITableDomGrid extends AITableGridBase {
3295
- ngOnInit() {
3296
- super.ngOnInit();
3297
- this.subscribeEvents();
3298
- }
3299
- openFieldMenu(e, field, fieldAction) {
3300
- const moreBtn = e.target.closest('.grid-field-action');
3301
- this.aiTableGridFieldService.openFieldMenu(this.aiTable, {
3302
- origin: moreBtn,
3303
- editOrigin: fieldAction,
3304
- fieldId: field._id,
3305
- fieldMenus: this.fieldMenus()
3306
- });
3307
- }
3308
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3309
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableDomGrid, isStandalone: true, selector: "ai-table-dom-grid", host: { classAttribute: "ai-table-grid ai-table-dom-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], usesInheritance: true, ngImport: i0, template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SelectOptionPipe, name: "selectOption" }, { kind: "pipe", type: SelectOptionsPipe, name: "selectOptions" }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "ngmodule", type: ThyPopoverModule }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyRate, selector: "thy-rate", inputs: ["thyCount", "thyDisabled", "thyAllowHalf", "thyAllowClear", "thyTooltips", "thyIconTemplate"], outputs: ["thyItemHoverChange"] }, { kind: "component", type: ThyProgress, selector: "thy-progress", inputs: ["thyType", "thySize", "thyValue", "thyMax", "thyTips", "thyShape", "thyGapDegree", "thyGapPosition", "thyStrokeWidth"] }, { kind: "pipe", type: ThyDatePickerFormatPipe, name: "thyDatePickerFormat" }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyCheckboxModule }, { kind: "component", type: i3$1.ThyCheckbox, selector: "thy-checkbox,[thy-checkbox],[thyCheckbox]", inputs: ["thyIndeterminate"] }, { kind: "ngmodule", type: ThyAvatarModule }, { kind: "component", type: i4.ThyAvatar, selector: "thy-avatar", inputs: ["thyShowName", "thySrc", "thyName", "thySize", "thyShowRemove", "thyRemovable", "thyImgClass", "thyDisabled", "thyLoading", "thyFetchPriority"], outputs: ["thyOnRemove", "thyRemove", "thyError"] }, { kind: "component", type: i4.ThyAvatarList, selector: "thy-avatar-list", inputs: ["thyMode", "thyAvatarSize"] }, { kind: "pipe", type: IsSelectRecordPipe, name: "isSelectRecord" }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "pipe", type: UserPipe, name: "user" }, { kind: "pipe", type: SelectSettingPipe, name: "selectSetting" }, { kind: "pipe", type: MemberSettingPipe, name: "memberSetting" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3310
- }
3311
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, decorators: [{
3312
- type: Component,
3313
- args: [{ selector: 'ai-table-dom-grid', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
3314
- class: 'ai-table-grid ai-table-dom-grid'
3315
- }, imports: [
3316
- NgClass,
3317
- NgComponentOutlet,
3318
- CommonModule,
3319
- FormsModule,
3320
- SelectOptionPipe,
3321
- SelectOptionsPipe,
3322
- ThyTag,
3323
- ThyPopoverModule,
3324
- ThyIcon,
3325
- ThyRate,
3326
- ThyProgress,
3327
- AITableFieldSetting,
3328
- ThyDatePickerFormatPipe,
3329
- ThyFlexibleText,
3330
- ThyStopPropagationDirective,
3331
- AITableFieldMenu,
3332
- ThyAction,
3333
- ThyDropdownDirective,
3334
- ThyDropdownMenuComponent,
3335
- ThyCheckboxModule,
3336
- ProgressEditorComponent,
3337
- ThyAvatarModule,
3338
- NgTemplateOutlet,
3339
- IsSelectRecordPipe,
3340
- ProgressEditorComponent,
3341
- SelectOptionComponent,
3342
- UserPipe,
3343
- SelectSettingPipe,
3344
- MemberSettingPipe
3345
- ], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n" }]
3346
- }] });
3347
-
3348
- const KO_CONTAINER_TOKEN = new InjectionToken('KO_CONTAINER_TOKEN');
3349
-
3350
- function updatePicture(node) {
3351
- const drawingNode = node.getLayer() || node.getStage();
3352
- if (drawingNode) {
3353
- drawingNode.batchDraw();
3354
- }
3355
- }
3356
-
3357
- // adapted FROM: https://github.com/lavrton/react-konva/blob/master/src/react-konva-fiber.js
3358
- function applyNodeProps(component, props = {}, oldProps = {}) {
3359
- if ('id' in props) {
3360
- const message = `You are using "id" attribute for Konva node. In some very rare cases it may produce bugs. Currently we recommend not to use it and use "name" attribute instead.`;
3361
- console.warn(message);
3362
- }
3363
- const instance = component.getNode();
3364
- const updatedProps = {};
3365
- let hasUpdates = false;
3366
- Object.keys(oldProps).forEach((key) => {
3367
- const isEvent = key.slice(0, 2) === 'ko';
3368
- const propChanged = oldProps[key] !== props[key];
3369
- if (isEvent && propChanged) {
3370
- let eventName = key.slice(2).toLowerCase();
3371
- if (eventName.slice(0, 7) === 'content') {
3372
- eventName = 'content' + eventName.slice(7, 8).toUpperCase() + eventName.slice(8);
3373
- }
3374
- instance.off(eventName, oldProps[key]);
3375
- }
3376
- const toRemove = !Object.hasOwn(props, key);
3377
- if (toRemove) {
3378
- instance.setAttr(key, undefined);
3379
- }
3380
- });
3381
- Object.keys(props).forEach((key) => {
3382
- const isEvent = key.slice(0, 2) === 'ko';
3383
- const toAdd = oldProps[key] !== props[key];
3384
- if (isEvent && toAdd) {
3385
- let eventName = key.slice(2).toLowerCase();
3386
- if (eventName.slice(0, 7) === 'content') {
3387
- eventName = 'content' + eventName.slice(7, 8).toUpperCase() + eventName.slice(8);
3388
- }
3389
- if (props[key]) {
3390
- instance.off(eventName);
3391
- instance.on(eventName, (event) => {
3392
- props[key]({
3393
- angularComponent: component,
3394
- event
3395
- });
3396
- });
3397
- }
3398
- }
3399
- if (!isEvent && (props[key] !== oldProps[key] || props[key] !== instance.getAttr(key))) {
3400
- hasUpdates = true;
3401
- updatedProps[key] = props[key];
3402
- }
3403
- });
3404
- if (hasUpdates) {
3405
- instance.setAttrs(updatedProps);
3406
- updatePicture(instance);
3407
- let val;
3408
- Object.keys(updatedProps).forEach((prop) => {
3409
- val = updatedProps[prop];
3410
- if (val instanceof Image && !val.complete) {
3411
- const node = instance;
3412
- val.addEventListener('load', function () {
3413
- const layer = node.getLayer();
3414
- if (layer) {
3415
- layer.batchDraw();
3416
- }
3417
- });
3418
- }
3419
- });
3420
- }
3421
- }
3422
-
3423
- function camelize(str) {
3424
- return str
3425
- .replace(/^\w|[A-Z]|\b\w/g, function (letter, index) {
3426
- return index == 0 ? letter.toLowerCase() : letter.toUpperCase();
3427
- })
3428
- .replace(/\s+/g, '');
3429
- }
3430
- function capitalizeFirstLetter(string) {
3431
- return string.charAt(0).toUpperCase() + string.slice(1);
3432
- }
3433
- function getName(componentTag) {
3434
- return capitalizeFirstLetter(camelize(componentTag.slice(3).replace('-', ' ')));
3435
- }
3436
- function createListener(instance) {
3437
- const output = {};
3438
- [
3439
- 'koMouseover',
3440
- 'koMousemove',
3441
- 'koMouseout',
3442
- 'koMouseenter',
3443
- 'koMouseleave',
3444
- 'koMousedown',
3445
- 'koMouseup',
3446
- 'koWheel',
3447
- 'koContextmenu',
3448
- 'koClick',
3449
- 'koDblclick',
3450
- 'koTouchstart',
3451
- 'koTouchmove',
3452
- 'koTouchend',
3453
- 'koTap',
3454
- 'koDbltap',
3455
- 'koDragstart',
3456
- 'koDragmove',
3457
- 'koDragend'
3458
- ].forEach((eventName) => {
3459
- const name = eventName;
3460
- const eventEmitter = instance[name];
3461
- if (eventEmitter.observed) {
3462
- output[eventName] = eventEmitter.emit.bind(eventEmitter);
3463
- }
3464
- });
3465
- return output;
3466
- }
3467
-
3468
- class KoShape {
3469
- constructor() {
3470
- this.config = input();
3471
- this.koMouseover = new EventEmitter();
3472
- this.koMousemove = new EventEmitter();
3473
- this.koMouseout = new EventEmitter();
3474
- this.koMouseenter = new EventEmitter();
3475
- this.koMouseleave = new EventEmitter();
3476
- this.koMousedown = new EventEmitter();
3477
- this.koMouseup = new EventEmitter();
3478
- this.koWheel = new EventEmitter();
3479
- this.koContextmenu = new EventEmitter();
3480
- this.koClick = new EventEmitter();
3481
- this.koDblclick = new EventEmitter();
3482
- this.koTouchstart = new EventEmitter();
3483
- this.koTouchmove = new EventEmitter();
3484
- this.koTouchend = new EventEmitter();
3485
- this.koTap = new EventEmitter();
3486
- this.koDbltap = new EventEmitter();
3487
- this.koDragstart = new EventEmitter();
3488
- this.koDragmove = new EventEmitter();
3489
- this.koDragend = new EventEmitter();
3490
- this.elementRef = inject((ElementRef));
3491
- this.container = inject(KO_CONTAINER_TOKEN, { skipSelf: true });
3492
- this.cacheProps = {};
3493
- this.nameNode = getName(this.elementRef.nativeElement.localName);
3494
- effect(() => {
3495
- if (this.config()) {
3496
- this.updateNode(this.config());
3497
- }
3498
- });
3499
- }
3500
- getNode() {
3501
- return this._node;
3502
- }
3503
- ngOnInit() {
3504
- this.initKonva();
3505
- }
3506
- initKonva() {
3507
- if (!this._node) {
3508
- this._node = new Shape();
3509
- }
3510
- if (this.nameNode === 'Shape') {
3511
- this._node = new Shape();
3512
- }
3513
- else if (this.nameNode === 'Sprite') {
3514
- this._node = new Sprite(this.config());
3515
- }
3516
- else {
3517
- this._node = new Konva[this.nameNode](undefined);
3518
- }
3519
- const animationStage = this._node.to.bind(this._node);
3520
- this._node.to = (newConfig) => {
3521
- animationStage(newConfig);
3522
- setTimeout(() => {
3523
- Object.keys(this._node.attrs).forEach((key) => {
3524
- if (typeof this._node.attrs[key] !== 'function') {
3525
- this.config()[key] = this._node.attrs[key];
3526
- }
3527
- });
3528
- }, 200);
3529
- };
3530
- if (this.config()) {
3531
- this.updateNode(this.config());
3096
+ const animationStage = this._node.to.bind(this._node);
3097
+ this._node.to = (newConfig) => {
3098
+ animationStage(newConfig);
3099
+ setTimeout(() => {
3100
+ Object.keys(this._node.attrs).forEach((key) => {
3101
+ if (typeof this._node.attrs[key] !== 'function') {
3102
+ this.config()[key] = this._node.attrs[key];
3103
+ }
3104
+ });
3105
+ }, 200);
3106
+ };
3107
+ if (this.config()) {
3108
+ this.updateNode(this.config());
3532
3109
  }
3533
3110
  }
3534
3111
  updateNode(config) {
@@ -3625,309 +3202,74 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
3625
3202
  }]
3626
3203
  }] });
3627
3204
 
3628
- class KoStage {
3629
- constructor() {
3630
- this.config = input();
3631
- this.koMouseover = new EventEmitter();
3632
- this.koMousemove = new EventEmitter();
3633
- this.koMouseout = new EventEmitter();
3634
- this.koMouseenter = new EventEmitter();
3635
- this.koMouseleave = new EventEmitter();
3636
- this.koMousedown = new EventEmitter();
3637
- this.koMouseup = new EventEmitter();
3638
- this.koWheel = new EventEmitter();
3639
- this.koContextmenu = new EventEmitter();
3640
- this.koClick = new EventEmitter();
3641
- this.koDblclick = new EventEmitter();
3642
- this.koTouchstart = new EventEmitter();
3643
- this.koTouchmove = new EventEmitter();
3644
- this.koTouchend = new EventEmitter();
3645
- this.koTap = new EventEmitter();
3646
- this.koDbltap = new EventEmitter();
3647
- this.koDragstart = new EventEmitter();
3648
- this.koDragmove = new EventEmitter();
3649
- this.koDragend = new EventEmitter();
3650
- this.cacheProps = {};
3651
- this.nodeContainer = inject(ElementRef).nativeElement;
3652
- effect(() => {
3653
- if (this.config()) {
3654
- if (!this._stage) {
3655
- this.initStage();
3656
- }
3657
- this.updateNode(this.config());
3658
- }
3659
- });
3660
- }
3661
- ngOnInit() {
3662
- this.initStage();
3663
- }
3664
- getNode() {
3665
- return this._stage;
3666
- }
3667
- initStage() {
3668
- this._stage = new Stage({
3669
- ...this.config(),
3670
- container: this.nodeContainer
3671
- });
3672
- }
3673
- updateNode(config) {
3674
- const props = {
3675
- ...config,
3676
- ...createListener(this)
3677
- };
3678
- applyNodeProps(this, props, this.cacheProps);
3679
- this.cacheProps = props;
3680
- }
3681
- ngOnDestroy() {
3682
- this._stage?.destroy();
3683
- }
3684
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3685
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: KoStage, isStandalone: true, selector: "ko-stage", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { koMouseover: "koMouseover", koMousemove: "koMousemove", koMouseout: "koMouseout", koMouseenter: "koMouseenter", koMouseleave: "koMouseleave", koMousedown: "koMousedown", koMouseup: "koMouseup", koWheel: "koWheel", koContextmenu: "koContextmenu", koClick: "koClick", koDblclick: "koDblclick", koTouchstart: "koTouchstart", koTouchmove: "koTouchmove", koTouchend: "koTouchend", koTap: "koTap", koDbltap: "koDbltap", koDragstart: "koDragstart", koDragmove: "koDragmove", koDragend: "koDragend" }, providers: [
3686
- {
3687
- provide: KO_CONTAINER_TOKEN,
3688
- useExisting: KoStage
3689
- }
3690
- ], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3691
- }
3692
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, decorators: [{
3693
- type: Component,
3694
- args: [{
3695
- selector: 'ko-stage',
3696
- standalone: true,
3697
- template: `<ng-content></ng-content>`,
3698
- providers: [
3699
- {
3700
- provide: KO_CONTAINER_TOKEN,
3701
- useExisting: KoStage
3702
- }
3703
- ],
3704
- changeDetection: ChangeDetectionStrategy.OnPush
3705
- }]
3706
- }], ctorParameters: () => [], propDecorators: { koMouseover: [{
3707
- type: Output
3708
- }], koMousemove: [{
3709
- type: Output
3710
- }], koMouseout: [{
3711
- type: Output
3712
- }], koMouseenter: [{
3713
- type: Output
3714
- }], koMouseleave: [{
3715
- type: Output
3716
- }], koMousedown: [{
3717
- type: Output
3718
- }], koMouseup: [{
3719
- type: Output
3720
- }], koWheel: [{
3721
- type: Output
3722
- }], koContextmenu: [{
3723
- type: Output
3724
- }], koClick: [{
3725
- type: Output
3726
- }], koDblclick: [{
3727
- type: Output
3728
- }], koTouchstart: [{
3729
- type: Output
3730
- }], koTouchmove: [{
3731
- type: Output
3732
- }], koTouchend: [{
3733
- type: Output
3734
- }], koTap: [{
3735
- type: Output
3736
- }], koDbltap: [{
3737
- type: Output
3738
- }], koDragstart: [{
3739
- type: Output
3740
- }], koDragmove: [{
3741
- type: Output
3742
- }], koDragend: [{
3743
- type: Output
3744
- }] } });
3745
-
3746
- class KoComponent extends Component {
3747
- }
3748
-
3749
- const KoShapeTypes = {
3750
- Arc,
3751
- Arrow,
3752
- Circle,
3753
- Ellipse,
3754
- Image: Image$1,
3755
- Label,
3756
- Tag,
3757
- Line,
3758
- Path,
3759
- Rect,
3760
- RegularPolygon,
3761
- Ring,
3762
- Star,
3763
- Text,
3764
- TextPath,
3765
- Transformer,
3766
- Wedge,
3767
- Group,
3768
- Layer,
3769
- FastLayer
3770
- };
3771
-
3772
- class AITableIcon {
3205
+ class AITableText {
3773
3206
  constructor() {
3774
3207
  this.config = input.required();
3775
- this.groupConfig = computed(() => {
3776
- const { x, y, listening } = this.config();
3777
- return { x, y, listening };
3778
- });
3779
- this.squareShapeConfig = computed(() => {
3780
- const { name, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, strokeWidth = 1, background, cornerRadius, opacity } = this.config();
3781
- return {
3782
- name,
3783
- width: backgroundWidth || size,
3784
- height: backgroundHeight || size,
3785
- strokeWidth: strokeWidth,
3786
- fill: background || Colors.transparent,
3787
- cornerRadius,
3788
- opacity
3789
- };
3790
- });
3791
- this.iconConfig = computed(() => {
3792
- const { type, data, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, stroke, strokeWidth = 1, scaleX, scaleY, offsetX, offsetY, rotation, fill = Colors.gray600, transformsEnabled = 'position' } = this.config();
3793
- let pathData = data;
3794
- switch (type) {
3795
- case AITableCheckType.checked:
3796
- pathData = Check;
3797
- break;
3798
- case AITableCheckType.unchecked:
3799
- pathData = Unchecked;
3800
- break;
3801
- }
3208
+ // @Output() koClick = new EventEmitter<KoEventObject<MouseEvent>>();
3209
+ this.koClick = output();
3210
+ this.koMouseMove = output();
3211
+ this.textConfig = computed(() => {
3212
+ const { x, y, width, height, text, padding, align = DEFAULT_TEXT_ALIGN_LEFT, verticalAlign = DEFAULT_TEXT_VERTICAL_ALIGN_MIDDLE, fill = DEFAULT_TEXT_FILL, textDecoration, fontSize = DEFAULT_FONT_SIZE, fontStyle = DEFAULT_FONT_STYLE, ellipsis = DEFAULT_TEXT_ELLIPSIS, wrap = DEFAULT_TEXT_WRAP, transformsEnabled = DEFAULT_TEXT_TRANSFORMS_ENABLED, listening = DEFAULT_TEXT_LISTENING, fontFamily = DEFAULT_FONT_FAMILY, ...rest } = this.config();
3213
+ const tmpText = new Konva.Text({
3214
+ text,
3215
+ fontSize,
3216
+ fontFamily
3217
+ });
3218
+ const textBounds = tmpText.getClientRect();
3802
3219
  return {
3803
- x: backgroundWidth && (backgroundWidth - size * (scaleX || 1)) / 2,
3804
- y: backgroundHeight && (backgroundHeight - size * (scaleY || 1)) / 2,
3805
- data: pathData,
3806
- width: size,
3807
- height: size,
3220
+ x,
3221
+ y,
3222
+ width,
3223
+ height,
3224
+ text,
3225
+ padding,
3226
+ align,
3227
+ verticalAlign,
3808
3228
  fill,
3809
- offsetX,
3810
- offsetY,
3811
- scaleX,
3812
- scaleY,
3813
- rotation,
3814
- stroke,
3815
- strokeWidth,
3229
+ textDecoration,
3230
+ fontSize,
3231
+ fontStyle,
3232
+ ellipsis,
3233
+ wrap,
3816
3234
  transformsEnabled,
3817
- perfectDrawEnabled: false,
3818
- listening: false
3235
+ listening,
3236
+ fontFamily,
3237
+ hitFunc: function (context) {
3238
+ context.beginPath();
3239
+ context.rect(AI_TABLE_OFFSET, (height - textBounds.height) / 2 - AI_TABLE_OFFSET, textBounds.width, textBounds.height);
3240
+ context.closePath();
3241
+ context.fillStrokeShape(this);
3242
+ },
3243
+ ...rest
3819
3244
  };
3820
3245
  });
3821
3246
  }
3822
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3823
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableIcon, isStandalone: true, selector: "ai-table-icon", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
3824
- <ko-group [config]="groupConfig()">
3825
- <ko-rect [config]="squareShapeConfig()"></ko-rect>
3826
- <ko-path [config]="iconConfig()"></ko-path>
3827
- </ko-group>
3828
- `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3247
+ onClick(e) {
3248
+ this.koClick.emit(e);
3249
+ }
3250
+ onMousemove(e) {
3251
+ this.koMouseMove.emit(e);
3252
+ }
3253
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableText, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3254
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableText, isStandalone: true, selector: "ai-table-text", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { koClick: "koClick", koMouseMove: "koMouseMove" }, ngImport: i0, template: ` <ko-text [config]="textConfig()" (koClick)="onClick($event)" (koMousemove)="onMousemove($event)"></ko-text> `, isInline: true, dependencies: [{ kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3829
3255
  }
3830
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, decorators: [{
3256
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableText, decorators: [{
3831
3257
  type: Component,
3832
3258
  args: [{
3833
- selector: 'ai-table-icon',
3834
- template: `
3835
- <ko-group [config]="groupConfig()">
3836
- <ko-rect [config]="squareShapeConfig()"></ko-rect>
3837
- <ko-path [config]="iconConfig()"></ko-path>
3838
- </ko-group>
3839
- `,
3259
+ selector: 'ai-table-text',
3260
+ template: ` <ko-text [config]="textConfig()" (koClick)="onClick($event)" (koMousemove)="onMousemove($event)"></ko-text> `,
3840
3261
  standalone: true,
3841
- imports: [KoContainer, KoShape],
3262
+ imports: [KoShape],
3842
3263
  changeDetection: ChangeDetectionStrategy.OnPush
3843
3264
  }]
3844
3265
  }] });
3845
3266
 
3846
- class AITableAddField {
3847
- constructor() {
3848
- this.config = input.required();
3849
- this.btnWidth = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
3850
- this.x = computed(() => {
3851
- const lastColumnWidth = this.config().coordinate.getColumnWidth(this.config().columnStopIndex);
3852
- const lastColumnOffset = this.config().coordinate.getColumnOffset(this.config().columnStopIndex);
3853
- return lastColumnWidth + lastColumnOffset;
3854
- });
3855
- this.rectConfig = computed(() => {
3856
- const { pointPosition: { targetName }, readonly } = this.config();
3857
- const fill = targetName === AI_TABLE_FIELD_ADD_BUTTON ? Colors.gray80 : Colors.white;
3858
- return {
3859
- name: generateTargetName({
3860
- targetName: AI_TABLE_FIELD_ADD_BUTTON,
3861
- fieldId: this.config().fields[this.config().columnStopIndex]._id,
3862
- mouseStyle: readonly ? 'default' : 'pointer'
3863
- }),
3864
- x: AI_TABLE_OFFSET,
3865
- y: AI_TABLE_OFFSET,
3866
- width: this.config().coordinate.containerWidth - this.x() < this.btnWidth
3867
- ? this.btnWidth
3868
- : this.config().coordinate.containerWidth - this.x(),
3869
- height: this.config().coordinate.rowInitSize,
3870
- stroke: Colors.gray200,
3871
- strokeWidth: 1,
3872
- listening: true,
3873
- fill
3874
- };
3875
- });
3876
- this.addIconConfig = computed(() => {
3877
- const { readonly } = this.config();
3878
- const offsetY = (this.config().coordinate.rowInitSize - AI_TABLE_ICON_COMMON_SIZE) / 2;
3879
- return {
3880
- x: AI_TABLE_CELL_PADDING,
3881
- y: offsetY,
3882
- data: AddOutlinedPath,
3883
- fill: Colors.gray600,
3884
- listening: false,
3885
- visible: isNil(readonly) ? true : !readonly
3886
- };
3887
- });
3888
- }
3889
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3890
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableAddField, isStandalone: true, selector: "ai-table-add-field", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
3891
- <ko-group [config]="{ x: x() }">
3892
- <ko-group>
3893
- <ko-rect [config]="rectConfig()"></ko-rect>
3894
- </ko-group>
3895
- <ko-group>
3896
- @if (addIconConfig().visible) {
3897
- <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
3898
- }
3899
- </ko-group>
3900
- </ko-group>
3901
- `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableIcon, selector: "ai-table-icon", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3902
- }
3903
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, decorators: [{
3904
- type: Component,
3905
- args: [{
3906
- selector: 'ai-table-add-field',
3907
- template: `
3908
- <ko-group [config]="{ x: x() }">
3909
- <ko-group>
3910
- <ko-rect [config]="rectConfig()"></ko-rect>
3911
- </ko-group>
3912
- <ko-group>
3913
- @if (addIconConfig().visible) {
3914
- <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
3915
- }
3916
- </ko-group>
3917
- </ko-group>
3918
- `,
3919
- standalone: true,
3920
- imports: [KoContainer, KoShape, AITableIcon],
3921
- changeDetection: ChangeDetectionStrategy.OnPush
3922
- }]
3923
- }] });
3924
-
3925
- // 用于正确地分割字符串,包括表情符号
3926
- const graphemeSplitter = new GraphemeSplitter();
3927
- /**
3928
- * 用于在 Canvas 上进行的各种绘图操作,包含了文本绘制、矩形绘制、路径绘制以及一些几何计算等功能
3929
- */
3930
- class Drawer {
3267
+ // 用于正确地分割字符串,包括表情符号
3268
+ const graphemeSplitter = new GraphemeSplitter();
3269
+ /**
3270
+ * 用于在 Canvas 上进行的各种绘图操作,包含了文本绘制、矩形绘制、路径绘制以及一些几何计算等功能
3271
+ */
3272
+ class Drawer {
3931
3273
  constructor() {
3932
3274
  this.ctx = TextMeasure().context;
3933
3275
  this.needDraw = false;
@@ -4838,22 +4180,861 @@ class Drawer {
4838
4180
  this.ctx.rotate(-psi);
4839
4181
  this.ctx.translate(-cx, -cy);
4840
4182
  break;
4841
- case 'z':
4842
- isClosed = true;
4843
- this.ctx.closePath();
4183
+ case 'z':
4184
+ isClosed = true;
4185
+ this.ctx.closePath();
4186
+ break;
4187
+ }
4188
+ }
4189
+ if (!isClosed) {
4190
+ this.ctx.stroke();
4191
+ }
4192
+ else {
4193
+ this.ctx.fill();
4194
+ }
4195
+ this.ctx.restore();
4196
+ }
4197
+ }
4198
+ const drawer = new Drawer();
4199
+
4200
+ class AITableCellLink {
4201
+ constructor() {
4202
+ this.config = input();
4203
+ this.textOffset = AI_TABLE_CELL_PADDING + AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE;
4204
+ this.render = computed(() => this.config()?.render);
4205
+ this.transformValue = computed(() => this.render()?.transformValue);
4206
+ this.showLink = computed(() => !!this.transformValue()?.text);
4207
+ this.textConfig = computed(() => {
4208
+ const render = this.config()?.render;
4209
+ if (render) {
4210
+ const { x, y, transformValue, field, columnWidth, rowHeight, style, zIndex } = render;
4211
+ let textRender = transformValue.text;
4212
+ if (textRender == null) {
4213
+ return;
4214
+ }
4215
+ textRender = textRender.replace(/\r|\n/g, ' ');
4216
+ const fontWeight = style?.fontWeight;
4217
+ const textMaxWidth = columnWidth - 2 * AI_TABLE_CELL_PADDING;
4218
+ const { text, textWidth } = drawer.textEllipsis({
4219
+ text: textRender,
4220
+ maxWidth: textMaxWidth,
4221
+ fontWeight
4222
+ });
4223
+ return {
4224
+ x,
4225
+ y,
4226
+ text,
4227
+ wrap: 'none',
4228
+ width: textWidth,
4229
+ fillStyle: Colors.primary,
4230
+ fill: Colors.primary,
4231
+ height: rowHeight + 2,
4232
+ lineHeight: 1.84,
4233
+ listening: true,
4234
+ ellipsis: true,
4235
+ zIndex
4236
+ };
4237
+ }
4238
+ return;
4239
+ });
4240
+ }
4241
+ static { this.fieldType = AITableFieldType.link; }
4242
+ linkClick(e) {
4243
+ e.event.cancelBubble = true;
4244
+ window.open(this.transformValue().url, '_blank', 'noopener,noreferrer');
4245
+ }
4246
+ linkMouseMove(e) {
4247
+ e.event.cancelBubble = true;
4248
+ const { aiTable, coordinate } = this.config();
4249
+ const targetName = e.event.target.name();
4250
+ const gridStage = e.event.currentTarget.getStage();
4251
+ const pos = gridStage?.getPointerPosition();
4252
+ if (pos == null)
4253
+ return;
4254
+ const { context } = aiTable;
4255
+ const { x, y } = pos;
4256
+ const curMousePosition = getMousePosition(x, y, coordinate, AITable.getVisibleFields(aiTable), context, targetName);
4257
+ handleMouseStyle(AI_TABLE_FIELD_HEAD_MORE, curMousePosition.areaType, coordinate.container);
4258
+ }
4259
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableCellLink, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4260
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableCellLink, isStandalone: true, selector: "ai-table-link", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
4261
+ @if (showLink()) {
4262
+ <ai-table-text [config]="textConfig()!" (koClick)="linkClick($event)" (koMouseMove)="linkMouseMove($event)"></ai-table-text>
4263
+ }
4264
+ `, isInline: true, dependencies: [{ kind: "component", type: AITableText, selector: "ai-table-text", inputs: ["config"], outputs: ["koClick", "koMouseMove"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4265
+ }
4266
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableCellLink, decorators: [{
4267
+ type: Component,
4268
+ args: [{
4269
+ selector: 'ai-table-link',
4270
+ template: `
4271
+ @if (showLink()) {
4272
+ <ai-table-text [config]="textConfig()!" (koClick)="linkClick($event)" (koMouseMove)="linkMouseMove($event)"></ai-table-text>
4273
+ }
4274
+ `,
4275
+ standalone: true,
4276
+ imports: [KoContainer, KoShape, AITableText],
4277
+ changeDetection: ChangeDetectionStrategy.OnPush
4278
+ }]
4279
+ }] });
4280
+
4281
+ var cellComponents = /*#__PURE__*/Object.freeze({
4282
+ __proto__: null,
4283
+ AITableCellLink: AITableCellLink
4284
+ });
4285
+
4286
+ const componentMap = {};
4287
+ Object.values(cellComponents).forEach((cellComponent) => {
4288
+ componentMap[cellComponent.fieldType] = cellComponent;
4289
+ });
4290
+
4291
+ function getHoverCell(aiTable) {
4292
+ const pointPosition = aiTable.context.pointPosition();
4293
+ const { fieldId, recordId } = getDetailByTargetName(pointPosition.realTargetName) ?? {};
4294
+ if (!recordId || !fieldId) {
4295
+ return;
4296
+ }
4297
+ const record = aiTable.recordsMap()[recordId];
4298
+ const field = aiTable.fieldsMap()[fieldId];
4299
+ if (!record || !field || !recordId || !fieldId) {
4300
+ return;
4301
+ }
4302
+ const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, fieldId]);
4303
+ const transformValue = transformCellValue(aiTable, field, cellValue) || {};
4304
+ if (Object.keys(transformValue).length === 0) {
4305
+ return;
4306
+ }
4307
+ const renderComponentDefinition = componentMap[field?.type];
4308
+ if (!renderComponentDefinition) {
4309
+ return;
4310
+ }
4311
+ return {
4312
+ field,
4313
+ recordId,
4314
+ fieldId,
4315
+ renderComponentDefinition
4316
+ };
4317
+ }
4318
+
4319
+ class AITableGridEventService {
4320
+ constructor() {
4321
+ this.dblClickEvent$ = new Subject();
4322
+ this.mousedownEvent$ = new Subject();
4323
+ this.mouseoverEvent$ = new Subject();
4324
+ this.globalMouseoverEvent$ = new Subject();
4325
+ this.globalMousedownEvent$ = new Subject();
4326
+ this.destroyRef = inject(DestroyRef);
4327
+ this.thyPopover = inject(ThyPopover);
4328
+ }
4329
+ initialize(aiTable, aiFieldRenderers) {
4330
+ this.aiTable = aiTable;
4331
+ this.aiFieldRenderers = aiFieldRenderers;
4332
+ }
4333
+ registerEvents(element) {
4334
+ fromEvent(element, 'dblclick', { passive: true })
4335
+ .pipe(takeUntilDestroyed(this.destroyRef))
4336
+ .subscribe((event) => {
4337
+ this.dblClickEvent$.next(event);
4338
+ });
4339
+ fromEvent(element, 'mouseover', { passive: true })
4340
+ .pipe(debounceTime(80), takeUntilDestroyed(this.destroyRef))
4341
+ .subscribe((event) => {
4342
+ this.mouseoverEvent$.next(event);
4343
+ });
4344
+ fromEvent(document, 'mouseover', { passive: true })
4345
+ .pipe(takeUntilDestroyed(this.destroyRef))
4346
+ .subscribe((event) => {
4347
+ this.globalMouseoverEvent$.next(event);
4348
+ });
4349
+ fromEvent(element, 'mousedown', { passive: true })
4350
+ .pipe(takeUntilDestroyed(this.destroyRef))
4351
+ .subscribe((event) => {
4352
+ this.mousedownEvent$.next(event);
4353
+ });
4354
+ fromEvent(document, 'mousedown', { passive: true })
4355
+ .pipe(takeUntilDestroyed(this.destroyRef))
4356
+ .subscribe((event) => {
4357
+ this.globalMousedownEvent$.next(event);
4358
+ });
4359
+ }
4360
+ getEditorComponent(type) {
4361
+ const filedRenderSchema = this.aiFieldRenderers && this.aiFieldRenderers[type];
4362
+ if (filedRenderSchema && filedRenderSchema.editor) {
4363
+ return filedRenderSchema.editor;
4364
+ }
4365
+ return GRID_CELL_EDITOR_MAP[type];
4366
+ }
4367
+ openEdit(cellDom) {
4368
+ const { x, y, width, height } = cellDom.getBoundingClientRect();
4369
+ const fieldId = cellDom.getAttribute('fieldId');
4370
+ const recordId = cellDom.getAttribute('recordId');
4371
+ const component = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
4372
+ const ref = this.thyPopover.open(component, {
4373
+ origin: cellDom,
4374
+ originPosition: {
4375
+ x: x - 1,
4376
+ y: y + 1,
4377
+ width: width + 2,
4378
+ height: height + 2
4379
+ },
4380
+ width: width + 1 + 'px',
4381
+ height: height + 2 + 'px',
4382
+ placement: 'top',
4383
+ offset: -(height + 4),
4384
+ minWidth: width,
4385
+ initialState: {
4386
+ fieldId: fieldId,
4387
+ recordId: recordId,
4388
+ aiTable: this.aiTable
4389
+ },
4390
+ panelClass: 'grid-cell-editor',
4391
+ outsideClosable: false,
4392
+ hasBackdrop: false,
4393
+ manualClosure: true,
4394
+ animationDisabled: true,
4395
+ autoAdaptive: true
4396
+ });
4397
+ return ref;
4398
+ }
4399
+ getOriginPosition(aiTable, options) {
4400
+ const { container, coordinate, recordId, fieldId, isHoverEdit } = options;
4401
+ const { scrollState } = aiTable.context;
4402
+ const { rowHeight, columnCount } = coordinate;
4403
+ const cell = [recordId, fieldId];
4404
+ const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, cell);
4405
+ const originX = coordinate.getColumnOffset(columnIndex);
4406
+ const originY = coordinate.getRowOffset(rowIndex);
4407
+ const columnWidth = coordinate.getColumnWidth(columnIndex);
4408
+ const { width: originWidth, offset: originOffset } = getCellHorizontalPosition({
4409
+ columnWidth,
4410
+ columnIndex,
4411
+ columnCount
4412
+ });
4413
+ const originRect = container.getBoundingClientRect();
4414
+ const isFrozenColumn = AITable.isFrozenColumn(aiTable, columnIndex);
4415
+ const scrollLeft = isFrozenColumn ? 0 : scrollState().scrollLeft;
4416
+ const scrollTop = scrollState().scrollTop;
4417
+ const originPosition = {
4418
+ x: originX + originOffset - scrollLeft + originRect.x,
4419
+ y: originY - scrollTop + originRect.y,
4420
+ width: originWidth,
4421
+ height: rowHeight
4422
+ };
4423
+ let x = originPosition.x + getEditorBoxOffset();
4424
+ let y = originPosition.y + getEditorBoxOffset();
4425
+ let width = getEditorSpace(originPosition.width);
4426
+ let height = getEditorSpace(originPosition.height);
4427
+ // hover 编辑组件无边框
4428
+ if (isHoverEdit) {
4429
+ x = originPosition.x + getHoverEditorBoxOffset();
4430
+ y = originPosition.y + getHoverEditorBoxOffset();
4431
+ width = getHoverEditorSpace(originPosition.width);
4432
+ height = getHoverEditorSpace(originPosition.height);
4433
+ }
4434
+ return {
4435
+ ...originPosition,
4436
+ x: x,
4437
+ y: y,
4438
+ width: width,
4439
+ height: height
4440
+ };
4441
+ }
4442
+ openCellEditor(aiTable, options) {
4443
+ const { container, recordId, fieldId, isHoverEdit, references } = options;
4444
+ const component = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
4445
+ const offsetOriginPosition = this.getOriginPosition(aiTable, options);
4446
+ this.cellEditorPopoverRef = this.thyPopover.open(component, {
4447
+ origin: container,
4448
+ originPosition: offsetOriginPosition,
4449
+ width: offsetOriginPosition.width + 'px',
4450
+ height: offsetOriginPosition.height + 'px',
4451
+ minWidth: offsetOriginPosition.width + 'px',
4452
+ placement: 'bottom',
4453
+ offset: -offsetOriginPosition.height,
4454
+ initialState: {
4455
+ fieldId: fieldId,
4456
+ recordId: recordId,
4457
+ references,
4458
+ aiTable: aiTable
4459
+ },
4460
+ panelClass: 'grid-cell-editor',
4461
+ outsideClosable: false,
4462
+ hasBackdrop: false,
4463
+ manualClosure: true,
4464
+ animationDisabled: true,
4465
+ autoAdaptive: true
4466
+ });
4467
+ if (this.cellEditorPopoverRef) {
4468
+ const wheelEvent = fromEvent(this.cellEditorPopoverRef.componentInstance.elementRef.nativeElement, 'wheel').subscribe((event) => {
4469
+ const field = aiTable.fieldsMap()[fieldId];
4470
+ if (field.type === AITableFieldType.text || field.type === AITableFieldType.richText) {
4471
+ return;
4472
+ }
4473
+ event.preventDefault();
4474
+ this.aiTable.context?.scrollAction({
4475
+ deltaX: event.deltaX,
4476
+ deltaY: event.deltaY,
4477
+ shiftKey: event.shiftKey,
4478
+ callback: () => {
4479
+ const originPosition = this.getOriginPosition(aiTable, options);
4480
+ const positionStrategy = this.cellEditorPopoverRef
4481
+ .getOverlayRef()
4482
+ .getConfig().positionStrategy;
4483
+ positionStrategy.setOrigin(originPosition);
4484
+ positionStrategy.apply();
4485
+ }
4486
+ });
4487
+ });
4488
+ this.cellEditorPopoverRef.afterClosed().subscribe(() => {
4489
+ wheelEvent.unsubscribe();
4490
+ this.cellEditorPopoverRef = null;
4491
+ });
4492
+ this.cellEditorPopoverRef.componentInstance.updateFieldValue.subscribe((value) => {
4493
+ options.updateFieldValue(value);
4494
+ });
4495
+ }
4496
+ return this.cellEditorPopoverRef;
4497
+ }
4498
+ closeCellEditor() {
4499
+ if (this.cellEditorPopoverRef) {
4500
+ this.cellEditorPopoverRef.close();
4501
+ this.cellEditorPopoverRef = null;
4502
+ }
4503
+ }
4504
+ getCurrentEditCell() {
4505
+ if (this.cellEditorPopoverRef) {
4506
+ const recordId = this.cellEditorPopoverRef.componentInstance?.recordId;
4507
+ const fieldId = this.cellEditorPopoverRef.componentInstance?.fieldId;
4508
+ if (recordId && fieldId) {
4509
+ return {
4510
+ recordId,
4511
+ fieldId
4512
+ };
4513
+ }
4514
+ return null;
4515
+ }
4516
+ return null;
4517
+ }
4518
+ openContextMenu(aiTable, options) {
4519
+ const { origin, position, menuItems, targetName, viewContainerRef } = options;
4520
+ const ref = this.thyPopover.open(AITableContextMenu, {
4521
+ origin: origin,
4522
+ originPosition: position,
4523
+ placement: 'bottomLeft',
4524
+ insideClosable: true,
4525
+ viewContainerRef,
4526
+ initialState: {
4527
+ aiTable,
4528
+ menuItems,
4529
+ targetName,
4530
+ position
4531
+ }
4532
+ });
4533
+ return ref;
4534
+ }
4535
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4536
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService }); }
4537
+ }
4538
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, decorators: [{
4539
+ type: Injectable
4540
+ }] });
4541
+
4542
+ class AITableGridBase {
4543
+ constructor() {
4544
+ this.aiRecords = model.required();
4545
+ this.aiFields = model.required();
4546
+ this.aiContextMenuItems = input([]);
4547
+ this.aiFieldConfig = input();
4548
+ this.aiReadonly = input();
4549
+ this.aiPlugins = input();
4550
+ this.aiReferences = input.required();
4551
+ this.aiBuildRenderDataFn = input();
4552
+ this.aiKeywords = input();
4553
+ this.AITableFieldType = AITableFieldType;
4554
+ this.AITableSelectOptionStyle = AITableSelectOptionStyle;
4555
+ this.isSelectedAll = computed(() => {
4556
+ return this.aiTable.selection().selectedRecords.size === this.aiRecords().length;
4557
+ });
4558
+ this.aiTableInitialized = output();
4559
+ this.aiAddRecord = output();
4560
+ this.aiAddField = output();
4561
+ this.aiUpdateFieldValue = output();
4562
+ this.fieldMenus = computed(() => {
4563
+ return this.aiFieldConfig()?.fieldMenus || [];
4564
+ });
4565
+ this.gridData = computed(() => {
4566
+ if (this.aiBuildRenderDataFn && this.aiBuildRenderDataFn() && this.aiTable) {
4567
+ return this.aiBuildRenderDataFn()(this.aiTable);
4568
+ }
4569
+ return {
4570
+ records: this.aiRecords(),
4571
+ fields: this.aiFields()
4572
+ };
4573
+ });
4574
+ this.ngZone = inject(NgZone);
4575
+ this.elementRef = inject(ElementRef);
4576
+ this.destroyRef = inject(DestroyRef);
4577
+ this.aiTableGridFieldService = inject(AITableGridFieldService);
4578
+ this.aiTableGridEventService = inject(AITableGridEventService);
4579
+ this.aiTableGridSelectionService = inject(AITableGridSelectionService);
4580
+ }
4581
+ ngOnInit() {
4582
+ this.initAITable();
4583
+ this.initService();
4584
+ }
4585
+ initAITable() {
4586
+ this.aiTable = createAITable(this.aiRecords, this.aiFields);
4587
+ this.aiPlugins()?.forEach((plugin) => {
4588
+ this.aiTable = plugin(this.aiTable);
4589
+ });
4590
+ this.aiTableInitialized.emit(this.aiTable);
4591
+ }
4592
+ initService() {
4593
+ this.aiTableGridEventService.initialize(this.aiTable, this.aiFieldConfig()?.fieldRenderers);
4594
+ this.aiTableGridSelectionService.initialize(this.aiTable);
4595
+ this.aiTableGridEventService.registerEvents(this.elementRef.nativeElement);
4596
+ this.aiTableGridFieldService.initAIFieldConfig(this.aiFieldConfig());
4597
+ AI_TABLE_GRID_FIELD_SERVICE_MAP.set(this.aiTable, this.aiTableGridFieldService);
4598
+ }
4599
+ addRecord() {
4600
+ const records = this.gridData().records;
4601
+ const recordCount = records.length;
4602
+ this.aiAddRecord.emit({
4603
+ originId: recordCount > 0 ? records[records.length - 1]._id : ''
4604
+ });
4605
+ }
4606
+ selectRecord(recordId) {
4607
+ this.aiTableGridSelectionService.selectRecord(recordId);
4608
+ }
4609
+ toggleSelectAll(checked) {
4610
+ this.aiTableGridSelectionService.toggleSelectAll(checked);
4611
+ }
4612
+ addField(gridColumnBlank, position) {
4613
+ const field = createDefaultField(this.aiTable, AITableFieldType.text);
4614
+ const popoverRef = this.aiTableGridFieldService.editFieldProperty(this.aiTable, {
4615
+ field,
4616
+ isUpdate: false,
4617
+ origin: gridColumnBlank,
4618
+ position
4619
+ });
4620
+ if (popoverRef && !this.aiFieldConfig()?.fieldSettingComponent) {
4621
+ popoverRef.componentInstance.addField.subscribe((defaultValue) => {
4622
+ const fields = this.gridData().fields;
4623
+ const fieldCount = fields.length;
4624
+ this.aiAddField.emit({
4625
+ originId: fieldCount > 0 ? fields[fields.length - 1]._id : '',
4626
+ defaultValue
4627
+ });
4628
+ });
4629
+ }
4630
+ }
4631
+ subscribeEvents() {
4632
+ this.ngZone.runOutsideAngular(() => {
4633
+ this.aiTableGridEventService.dblClickEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
4634
+ this.dblClick(event);
4635
+ });
4636
+ this.aiTableGridEventService.mousedownEvent$
4637
+ .pipe(mergeWith(this.aiTableGridEventService.globalMousedownEvent$), takeUntilDestroyed(this.destroyRef))
4638
+ .subscribe((event) => {
4639
+ this.aiTableGridSelectionService.updateSelect(event);
4640
+ });
4641
+ this.aiTableGridEventService.mouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
4642
+ this.mouseoverHandle(event);
4643
+ });
4644
+ this.aiTableGridEventService.globalMouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
4645
+ this.closeHoverCellEditor(event);
4646
+ });
4647
+ });
4648
+ }
4649
+ dblClick(event) {
4650
+ const cellDom = event.target.closest('.grid-cell');
4651
+ const type = cellDom && cellDom.getAttribute('type');
4652
+ if (type && DBL_CLICK_EDIT_TYPE.includes(type)) {
4653
+ this.aiTableGridEventService.openEdit(cellDom);
4654
+ }
4655
+ }
4656
+ mouseoverHandle(event) {
4657
+ if (this.mouseoverRef) {
4658
+ this.mouseoverRef?.close();
4659
+ }
4660
+ const cellDom = event.target.closest('.grid-cell');
4661
+ const type = cellDom && cellDom.getAttribute('type');
4662
+ if (type && MOUSEOVER_EDIT_TYPE.includes(type)) {
4663
+ this.mouseoverRef = this.aiTableGridEventService.openEdit(cellDom);
4664
+ }
4665
+ }
4666
+ closeHoverCellEditor(e) {
4667
+ if (this.mouseoverRef) {
4668
+ const hasGrid = e.target && e.target.closest('.ai-table-grid');
4669
+ const hasCellEditor = e.target && e.target.closest('.grid-cell-editor');
4670
+ if (!hasGrid && !hasCellEditor) {
4671
+ this.mouseoverRef.close();
4672
+ }
4673
+ }
4674
+ }
4675
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4676
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableGridBase, isStandalone: true, selector: "ai-table-grid-base", inputs: { aiRecords: { classPropertyName: "aiRecords", publicName: "aiRecords", isSignal: true, isRequired: true, transformFunction: null }, aiFields: { classPropertyName: "aiFields", publicName: "aiFields", isSignal: true, isRequired: true, transformFunction: null }, aiContextMenuItems: { classPropertyName: "aiContextMenuItems", publicName: "aiContextMenuItems", isSignal: true, isRequired: false, transformFunction: null }, aiFieldConfig: { classPropertyName: "aiFieldConfig", publicName: "aiFieldConfig", isSignal: true, isRequired: false, transformFunction: null }, aiReadonly: { classPropertyName: "aiReadonly", publicName: "aiReadonly", isSignal: true, isRequired: false, transformFunction: null }, aiPlugins: { classPropertyName: "aiPlugins", publicName: "aiPlugins", isSignal: true, isRequired: false, transformFunction: null }, aiReferences: { classPropertyName: "aiReferences", publicName: "aiReferences", isSignal: true, isRequired: true, transformFunction: null }, aiBuildRenderDataFn: { classPropertyName: "aiBuildRenderDataFn", publicName: "aiBuildRenderDataFn", isSignal: true, isRequired: false, transformFunction: null }, aiKeywords: { classPropertyName: "aiKeywords", publicName: "aiKeywords", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiRecords: "aiRecordsChange", aiFields: "aiFieldsChange", aiTableInitialized: "aiTableInitialized", aiAddRecord: "aiAddRecord", aiAddField: "aiAddField", aiUpdateFieldValue: "aiUpdateFieldValue" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4677
+ }
4678
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, decorators: [{
4679
+ type: Component,
4680
+ args: [{
4681
+ selector: 'ai-table-grid-base',
4682
+ template: '',
4683
+ standalone: true,
4684
+ changeDetection: ChangeDetectionStrategy.OnPush
4685
+ }]
4686
+ }] });
4687
+
4688
+ class AITableDomGrid extends AITableGridBase {
4689
+ ngOnInit() {
4690
+ super.ngOnInit();
4691
+ this.subscribeEvents();
4692
+ }
4693
+ openFieldMenu(e, field, fieldAction) {
4694
+ const moreBtn = e.target.closest('.grid-field-action');
4695
+ this.aiTableGridFieldService.openFieldMenu(this.aiTable, {
4696
+ origin: moreBtn,
4697
+ editOrigin: fieldAction,
4698
+ fieldId: field._id,
4699
+ fieldMenus: this.fieldMenus()
4700
+ });
4701
+ }
4702
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
4703
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableDomGrid, isStandalone: true, selector: "ai-table-dom-grid", host: { classAttribute: "ai-table-grid ai-table-dom-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], usesInheritance: true, ngImport: i0, template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SelectOptionPipe, name: "selectOption" }, { kind: "pipe", type: SelectOptionsPipe, name: "selectOptions" }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "ngmodule", type: ThyPopoverModule }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyRate, selector: "thy-rate", inputs: ["thyCount", "thyDisabled", "thyAllowHalf", "thyAllowClear", "thyTooltips", "thyIconTemplate"], outputs: ["thyItemHoverChange"] }, { kind: "component", type: ThyProgress, selector: "thy-progress", inputs: ["thyType", "thySize", "thyValue", "thyMax", "thyTips", "thyShape", "thyGapDegree", "thyGapPosition", "thyStrokeWidth"] }, { kind: "pipe", type: ThyDatePickerFormatPipe, name: "thyDatePickerFormat" }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyCheckboxModule }, { kind: "component", type: i3$1.ThyCheckbox, selector: "thy-checkbox,[thy-checkbox],[thyCheckbox]", inputs: ["thyIndeterminate"] }, { kind: "ngmodule", type: ThyAvatarModule }, { kind: "component", type: i4.ThyAvatar, selector: "thy-avatar", inputs: ["thyShowName", "thySrc", "thyName", "thySize", "thyShowRemove", "thyRemovable", "thyImgClass", "thyDisabled", "thyLoading", "thyFetchPriority"], outputs: ["thyOnRemove", "thyRemove", "thyError"] }, { kind: "component", type: i4.ThyAvatarList, selector: "thy-avatar-list", inputs: ["thyMode", "thyAvatarSize"] }, { kind: "pipe", type: IsSelectRecordPipe, name: "isSelectRecord" }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "pipe", type: UserPipe, name: "user" }, { kind: "pipe", type: SelectSettingPipe, name: "selectSetting" }, { kind: "pipe", type: MemberSettingPipe, name: "memberSetting" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4704
+ }
4705
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, decorators: [{
4706
+ type: Component,
4707
+ args: [{ selector: 'ai-table-dom-grid', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
4708
+ class: 'ai-table-grid ai-table-dom-grid'
4709
+ }, imports: [
4710
+ NgClass,
4711
+ NgComponentOutlet,
4712
+ CommonModule,
4713
+ FormsModule,
4714
+ SelectOptionPipe,
4715
+ SelectOptionsPipe,
4716
+ ThyTag,
4717
+ ThyPopoverModule,
4718
+ ThyIcon,
4719
+ ThyRate,
4720
+ ThyProgress,
4721
+ AITableFieldSetting,
4722
+ ThyDatePickerFormatPipe,
4723
+ ThyFlexibleText,
4724
+ ThyStopPropagationDirective,
4725
+ AITableFieldMenu,
4726
+ ThyAction,
4727
+ ThyDropdownDirective,
4728
+ ThyDropdownMenuComponent,
4729
+ ThyCheckboxModule,
4730
+ ProgressEditorComponent,
4731
+ ThyAvatarModule,
4732
+ NgTemplateOutlet,
4733
+ IsSelectRecordPipe,
4734
+ ProgressEditorComponent,
4735
+ SelectOptionComponent,
4736
+ UserPipe,
4737
+ SelectSettingPipe,
4738
+ MemberSettingPipe
4739
+ ], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n" }]
4740
+ }] });
4741
+
4742
+ class KoStage {
4743
+ constructor() {
4744
+ this.config = input();
4745
+ this.koMouseover = new EventEmitter();
4746
+ this.koMousemove = new EventEmitter();
4747
+ this.koMouseout = new EventEmitter();
4748
+ this.koMouseenter = new EventEmitter();
4749
+ this.koMouseleave = new EventEmitter();
4750
+ this.koMousedown = new EventEmitter();
4751
+ this.koMouseup = new EventEmitter();
4752
+ this.koWheel = new EventEmitter();
4753
+ this.koContextmenu = new EventEmitter();
4754
+ this.koClick = new EventEmitter();
4755
+ this.koDblclick = new EventEmitter();
4756
+ this.koTouchstart = new EventEmitter();
4757
+ this.koTouchmove = new EventEmitter();
4758
+ this.koTouchend = new EventEmitter();
4759
+ this.koTap = new EventEmitter();
4760
+ this.koDbltap = new EventEmitter();
4761
+ this.koDragstart = new EventEmitter();
4762
+ this.koDragmove = new EventEmitter();
4763
+ this.koDragend = new EventEmitter();
4764
+ this.cacheProps = {};
4765
+ this.nodeContainer = inject(ElementRef).nativeElement;
4766
+ effect(() => {
4767
+ if (this.config()) {
4768
+ if (!this._stage) {
4769
+ this.initStage();
4770
+ }
4771
+ this.updateNode(this.config());
4772
+ }
4773
+ });
4774
+ }
4775
+ ngOnInit() {
4776
+ this.initStage();
4777
+ }
4778
+ getNode() {
4779
+ return this._stage;
4780
+ }
4781
+ initStage() {
4782
+ this._stage = new Stage({
4783
+ ...this.config(),
4784
+ container: this.nodeContainer
4785
+ });
4786
+ }
4787
+ updateNode(config) {
4788
+ const props = {
4789
+ ...config,
4790
+ ...createListener(this)
4791
+ };
4792
+ applyNodeProps(this, props, this.cacheProps);
4793
+ this.cacheProps = props;
4794
+ }
4795
+ ngOnDestroy() {
4796
+ this._stage?.destroy();
4797
+ }
4798
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4799
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: KoStage, isStandalone: true, selector: "ko-stage", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { koMouseover: "koMouseover", koMousemove: "koMousemove", koMouseout: "koMouseout", koMouseenter: "koMouseenter", koMouseleave: "koMouseleave", koMousedown: "koMousedown", koMouseup: "koMouseup", koWheel: "koWheel", koContextmenu: "koContextmenu", koClick: "koClick", koDblclick: "koDblclick", koTouchstart: "koTouchstart", koTouchmove: "koTouchmove", koTouchend: "koTouchend", koTap: "koTap", koDbltap: "koDbltap", koDragstart: "koDragstart", koDragmove: "koDragmove", koDragend: "koDragend" }, providers: [
4800
+ {
4801
+ provide: KO_CONTAINER_TOKEN,
4802
+ useExisting: KoStage
4803
+ }
4804
+ ], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4805
+ }
4806
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, decorators: [{
4807
+ type: Component,
4808
+ args: [{
4809
+ selector: 'ko-stage',
4810
+ standalone: true,
4811
+ template: `<ng-content></ng-content>`,
4812
+ providers: [
4813
+ {
4814
+ provide: KO_CONTAINER_TOKEN,
4815
+ useExisting: KoStage
4816
+ }
4817
+ ],
4818
+ changeDetection: ChangeDetectionStrategy.OnPush
4819
+ }]
4820
+ }], ctorParameters: () => [], propDecorators: { koMouseover: [{
4821
+ type: Output
4822
+ }], koMousemove: [{
4823
+ type: Output
4824
+ }], koMouseout: [{
4825
+ type: Output
4826
+ }], koMouseenter: [{
4827
+ type: Output
4828
+ }], koMouseleave: [{
4829
+ type: Output
4830
+ }], koMousedown: [{
4831
+ type: Output
4832
+ }], koMouseup: [{
4833
+ type: Output
4834
+ }], koWheel: [{
4835
+ type: Output
4836
+ }], koContextmenu: [{
4837
+ type: Output
4838
+ }], koClick: [{
4839
+ type: Output
4840
+ }], koDblclick: [{
4841
+ type: Output
4842
+ }], koTouchstart: [{
4843
+ type: Output
4844
+ }], koTouchmove: [{
4845
+ type: Output
4846
+ }], koTouchend: [{
4847
+ type: Output
4848
+ }], koTap: [{
4849
+ type: Output
4850
+ }], koDbltap: [{
4851
+ type: Output
4852
+ }], koDragstart: [{
4853
+ type: Output
4854
+ }], koDragmove: [{
4855
+ type: Output
4856
+ }], koDragend: [{
4857
+ type: Output
4858
+ }] } });
4859
+
4860
+ class KoComponent extends Component {
4861
+ }
4862
+
4863
+ const KoShapeTypes = {
4864
+ Arc,
4865
+ Arrow,
4866
+ Circle,
4867
+ Ellipse,
4868
+ Image: Image$1,
4869
+ Label,
4870
+ Tag,
4871
+ Line,
4872
+ Path,
4873
+ Rect,
4874
+ RegularPolygon,
4875
+ Ring,
4876
+ Star,
4877
+ Text,
4878
+ TextPath,
4879
+ Transformer,
4880
+ Wedge,
4881
+ Group,
4882
+ Layer,
4883
+ FastLayer
4884
+ };
4885
+
4886
+ class AITableIcon {
4887
+ constructor() {
4888
+ this.config = input.required();
4889
+ this.groupConfig = computed(() => {
4890
+ const { x, y, listening } = this.config();
4891
+ return { x, y, listening };
4892
+ });
4893
+ this.squareShapeConfig = computed(() => {
4894
+ const { name, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, strokeWidth = 1, background, cornerRadius, opacity } = this.config();
4895
+ return {
4896
+ name,
4897
+ width: backgroundWidth || size,
4898
+ height: backgroundHeight || size,
4899
+ strokeWidth: strokeWidth,
4900
+ fill: background || Colors.transparent,
4901
+ cornerRadius,
4902
+ opacity
4903
+ };
4904
+ });
4905
+ this.iconConfig = computed(() => {
4906
+ const { type, data, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, stroke, strokeWidth = 1, scaleX, scaleY, offsetX, offsetY, rotation, fill = Colors.gray600, transformsEnabled = 'position' } = this.config();
4907
+ let pathData = data;
4908
+ switch (type) {
4909
+ case AITableCheckType.checked:
4910
+ pathData = Check;
4911
+ break;
4912
+ case AITableCheckType.unchecked:
4913
+ pathData = Unchecked;
4844
4914
  break;
4845
4915
  }
4846
- }
4847
- if (!isClosed) {
4848
- this.ctx.stroke();
4849
- }
4850
- else {
4851
- this.ctx.fill();
4852
- }
4853
- this.ctx.restore();
4916
+ return {
4917
+ x: backgroundWidth && (backgroundWidth - size * (scaleX || 1)) / 2,
4918
+ y: backgroundHeight && (backgroundHeight - size * (scaleY || 1)) / 2,
4919
+ data: pathData,
4920
+ width: size,
4921
+ height: size,
4922
+ fill,
4923
+ offsetX,
4924
+ offsetY,
4925
+ scaleX,
4926
+ scaleY,
4927
+ rotation,
4928
+ stroke,
4929
+ strokeWidth,
4930
+ transformsEnabled,
4931
+ perfectDrawEnabled: false,
4932
+ listening: false
4933
+ };
4934
+ });
4854
4935
  }
4936
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4937
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableIcon, isStandalone: true, selector: "ai-table-icon", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
4938
+ <ko-group [config]="groupConfig()">
4939
+ <ko-rect [config]="squareShapeConfig()"></ko-rect>
4940
+ <ko-path [config]="iconConfig()"></ko-path>
4941
+ </ko-group>
4942
+ `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4855
4943
  }
4856
- const drawer = new Drawer();
4944
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, decorators: [{
4945
+ type: Component,
4946
+ args: [{
4947
+ selector: 'ai-table-icon',
4948
+ template: `
4949
+ <ko-group [config]="groupConfig()">
4950
+ <ko-rect [config]="squareShapeConfig()"></ko-rect>
4951
+ <ko-path [config]="iconConfig()"></ko-path>
4952
+ </ko-group>
4953
+ `,
4954
+ standalone: true,
4955
+ imports: [KoContainer, KoShape],
4956
+ changeDetection: ChangeDetectionStrategy.OnPush
4957
+ }]
4958
+ }] });
4959
+
4960
+ class AITableAddField {
4961
+ constructor() {
4962
+ this.config = input.required();
4963
+ this.btnWidth = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
4964
+ this.x = computed(() => {
4965
+ const lastColumnWidth = this.config().coordinate.getColumnWidth(this.config().columnStopIndex);
4966
+ const lastColumnOffset = this.config().coordinate.getColumnOffset(this.config().columnStopIndex);
4967
+ return lastColumnWidth + lastColumnOffset;
4968
+ });
4969
+ this.rectConfig = computed(() => {
4970
+ const { pointPosition: { targetName }, readonly } = this.config();
4971
+ const fill = targetName === AI_TABLE_FIELD_ADD_BUTTON ? Colors.gray80 : Colors.white;
4972
+ return {
4973
+ name: generateTargetName({
4974
+ targetName: AI_TABLE_FIELD_ADD_BUTTON,
4975
+ fieldId: this.config().fields[this.config().columnStopIndex]._id,
4976
+ mouseStyle: readonly ? 'default' : 'pointer'
4977
+ }),
4978
+ x: AI_TABLE_OFFSET,
4979
+ y: AI_TABLE_OFFSET,
4980
+ width: this.config().coordinate.containerWidth - this.x() < this.btnWidth
4981
+ ? this.btnWidth
4982
+ : this.config().coordinate.containerWidth - this.x(),
4983
+ height: this.config().coordinate.rowInitSize,
4984
+ stroke: Colors.gray200,
4985
+ strokeWidth: 1,
4986
+ listening: true,
4987
+ fill
4988
+ };
4989
+ });
4990
+ this.addIconConfig = computed(() => {
4991
+ const { readonly } = this.config();
4992
+ const offsetY = (this.config().coordinate.rowInitSize - AI_TABLE_ICON_COMMON_SIZE) / 2;
4993
+ return {
4994
+ x: AI_TABLE_CELL_PADDING,
4995
+ y: offsetY,
4996
+ data: AddOutlinedPath,
4997
+ fill: Colors.gray600,
4998
+ listening: false,
4999
+ visible: isNil(readonly) ? true : !readonly
5000
+ };
5001
+ });
5002
+ }
5003
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5004
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableAddField, isStandalone: true, selector: "ai-table-add-field", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
5005
+ <ko-group [config]="{ x: x() }">
5006
+ <ko-group>
5007
+ <ko-rect [config]="rectConfig()"></ko-rect>
5008
+ </ko-group>
5009
+ <ko-group>
5010
+ @if (addIconConfig().visible) {
5011
+ <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
5012
+ }
5013
+ </ko-group>
5014
+ </ko-group>
5015
+ `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableIcon, selector: "ai-table-icon", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5016
+ }
5017
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, decorators: [{
5018
+ type: Component,
5019
+ args: [{
5020
+ selector: 'ai-table-add-field',
5021
+ template: `
5022
+ <ko-group [config]="{ x: x() }">
5023
+ <ko-group>
5024
+ <ko-rect [config]="rectConfig()"></ko-rect>
5025
+ </ko-group>
5026
+ <ko-group>
5027
+ @if (addIconConfig().visible) {
5028
+ <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
5029
+ }
5030
+ </ko-group>
5031
+ </ko-group>
5032
+ `,
5033
+ standalone: true,
5034
+ imports: [KoContainer, KoShape, AITableIcon],
5035
+ changeDetection: ChangeDetectionStrategy.OnPush
5036
+ }]
5037
+ }] });
4857
5038
 
4858
5039
  /**
4859
5040
  * 用于处理表格行或单元格的布局和绘制。
@@ -5062,7 +5243,7 @@ class CellDrawer extends Drawer {
5062
5243
  renderCellText(render, ctx) {
5063
5244
  const { x, y, transformValue, field, columnWidth, style } = render;
5064
5245
  const fieldType = field.type;
5065
- let renderText = fieldType === AITableFieldType.link ? transformValue.text : transformValue;
5246
+ let renderText = fieldType === AITableFieldType.link ? transformValue?.text : transformValue;
5066
5247
  if (renderText == null) {
5067
5248
  return;
5068
5249
  }
@@ -5511,10 +5692,10 @@ class CellDrawer extends Drawer {
5511
5692
  const avatarSize = AI_TABLE_MEMBER_AVATAR_SIZE;
5512
5693
  const itemHeight = AI_TABLE_CELL_MEMBER_ITEM_HEIGHT;
5513
5694
  const isOperating = isActive;
5514
- const isMulti = settings?.is_multiple;
5695
+ const isMultiple = settings?.is_multiple;
5515
5696
  let currentX = AI_TABLE_CELL_PADDING;
5516
5697
  let currentY = (AI_TABLE_ROW_BLANK_HEIGHT - avatarSize) / 2;
5517
- const itemOtherWidth = avatarSize + AI_TABLE_MEMBER_ITEM_PADDING_RIGHT + AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT;
5698
+ const itemOtherWidth = avatarSize + AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT;
5518
5699
  const maxHeight = isActive ? 130 - AI_TABLE_CELL_MULTI_PADDING_TOP : rowHeight - AI_TABLE_CELL_MULTI_PADDING_TOP;
5519
5700
  const maxTextWidth = isOperating
5520
5701
  ? columnWidth - 2 * AI_TABLE_CELL_PADDING - itemOtherWidth - AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE - 12
@@ -5526,7 +5707,7 @@ class CellDrawer extends Drawer {
5526
5707
  if (!userInfo)
5527
5708
  continue;
5528
5709
  const { uid, display_name, avatar } = userInfo;
5529
- const itemWidth = AITableAvatarSize.size24 + (isMulti ? AI_TABLE_CELL_MEMBER_ITEM_PADDING : 0);
5710
+ const itemWidth = AITableAvatarSize.size24 + (isMultiple ? AI_TABLE_CELL_MEMBER_ITEM_PADDING : 0);
5530
5711
  currentX = AI_TABLE_CELL_PADDING + index * itemWidth;
5531
5712
  let realMaxTextWidth = maxTextWidth < 0 ? 0 : maxTextWidth;
5532
5713
  if (index === 0 && isOperating) {
@@ -5569,6 +5750,22 @@ class CellDrawer extends Drawer {
5569
5750
  type: AITableAvatarType.member,
5570
5751
  size: AITableAvatarSize.size24
5571
5752
  });
5753
+ // 在非多选模式下显示名称
5754
+ if (!isMultiple) {
5755
+ const textX = x + currentX + AITableAvatarSize.size24 + AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT;
5756
+ this.text({
5757
+ x: textX,
5758
+ y: y + AI_TABLE_ROW_BLANK_HEIGHT / 2,
5759
+ text: this.textEllipsis({
5760
+ text: display_name || '',
5761
+ maxWidth: maxTextWidth,
5762
+ fontSize: AI_TABLE_COMMON_FONT_SIZE
5763
+ }).text,
5764
+ fillStyle: this.colors.gray800,
5765
+ fontSize: AI_TABLE_COMMON_FONT_SIZE,
5766
+ verticalAlign: DEFAULT_TEXT_VERTICAL_ALIGN_MIDDLE
5767
+ });
5768
+ }
5572
5769
  if (isMore) {
5573
5770
  ctx.save();
5574
5771
  ctx.globalAlpha = 0.3;
@@ -5722,6 +5919,7 @@ const createCells = (config) => {
5722
5919
  cellDrawer.initCtx(ctx);
5723
5920
  addRowLayout.initCtx(ctx);
5724
5921
  recordRowLayout.initCtx(ctx);
5922
+ const hoverCell = getHoverCell(aiTable);
5725
5923
  // 遍历列, 确定在哪些列上绘制单元格
5726
5924
  for (let columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) {
5727
5925
  if (columnIndex > columnCount - 1)
@@ -5811,6 +6009,11 @@ const createCells = (config) => {
5811
6009
  style,
5812
6010
  colors
5813
6011
  };
6012
+ // hover 组件渲染时,底层的 cell 渲染为空
6013
+ if (hoverCell && hoverCell.recordId === recordId && hoverCell.fieldId === fieldId) {
6014
+ render.cellValue = '';
6015
+ render.transformValue = '';
6016
+ }
5814
6017
  cellDrawer.initStyle(field, style);
5815
6018
  // 最后一列,且单元格内容存在,需要裁剪内容,以防止文本溢出单元格边界
5816
6019
  // 然后,根据计算好的样式和布局绘制单元格内容
@@ -5971,47 +6174,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
5971
6174
  }]
5972
6175
  }] });
5973
6176
 
5974
- class AITableText {
5975
- constructor() {
5976
- this.config = input.required();
5977
- this.textConfig = computed(() => {
5978
- const { x, y, width, height, text, padding, align = DEFAULT_TEXT_ALIGN_LEFT, verticalAlign = DEFAULT_TEXT_VERTICAL_ALIGN_MIDDLE, fill = DEFAULT_TEXT_FILL, textDecoration, fontSize = DEFAULT_FONT_SIZE, fontStyle = DEFAULT_FONT_STYLE, ellipsis = DEFAULT_TEXT_ELLIPSIS, wrap = DEFAULT_TEXT_WRAP, transformsEnabled = DEFAULT_TEXT_TRANSFORMS_ENABLED, listening = DEFAULT_TEXT_LISTENING, fontFamily = DEFAULT_FONT_FAMILY, ...rest } = this.config();
5979
- return {
5980
- x,
5981
- y,
5982
- width,
5983
- height,
5984
- text,
5985
- padding,
5986
- align,
5987
- verticalAlign,
5988
- fill,
5989
- textDecoration,
5990
- fontSize,
5991
- fontStyle,
5992
- ellipsis,
5993
- wrap,
5994
- transformsEnabled,
5995
- listening,
5996
- fontFamily,
5997
- ...rest
5998
- };
5999
- });
6000
- }
6001
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableText, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6002
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableText, isStandalone: true, selector: "ai-table-text", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: ` <ko-text [config]="textConfig()"></ko-text> `, isInline: true, dependencies: [{ kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6003
- }
6004
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableText, decorators: [{
6005
- type: Component,
6006
- args: [{
6007
- selector: 'ai-table-text',
6008
- template: ` <ko-text [config]="textConfig()"></ko-text> `,
6009
- standalone: true,
6010
- imports: [KoShape],
6011
- changeDetection: ChangeDetectionStrategy.OnPush
6012
- }]
6013
- }] });
6014
-
6015
6177
  class AITableFieldHead {
6016
6178
  constructor() {
6017
6179
  this.config = input.required();
@@ -6110,7 +6272,7 @@ class AITableFieldHead {
6110
6272
  }
6111
6273
  </ko-group>
6112
6274
  </ko-group>
6113
- `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableFieldIcon, selector: "ai-table-field-icon", inputs: ["config"] }, { kind: "component", type: AITableText, selector: "ai-table-text", inputs: ["config"] }, { kind: "component", type: AITableIcon, selector: "ai-table-icon", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6275
+ `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableFieldIcon, selector: "ai-table-field-icon", inputs: ["config"] }, { kind: "component", type: AITableText, selector: "ai-table-text", inputs: ["config"], outputs: ["koClick", "koMouseMove"] }, { kind: "component", type: AITableIcon, selector: "ai-table-icon", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6114
6276
  }
6115
6277
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableFieldHead, decorators: [{
6116
6278
  type: Component,
@@ -6651,6 +6813,100 @@ const createActiveCellBorder = (config) => {
6651
6813
  };
6652
6814
  };
6653
6815
 
6816
+ class AITableHoverCells {
6817
+ constructor() {
6818
+ this.config = input.required();
6819
+ this.componentMap = {};
6820
+ this.groupConfig = computed(() => {
6821
+ return {
6822
+ x: this.hoverCellConfig()?.x,
6823
+ y: this.hoverCellConfig()?.y
6824
+ };
6825
+ });
6826
+ this.hoverCellConfig = computed(() => {
6827
+ const { aiTable, coordinate } = this.config();
6828
+ const pointPosition = aiTable.context.pointPosition();
6829
+ const hoverCell = this.hoverCell();
6830
+ if (!hoverCell) {
6831
+ return;
6832
+ }
6833
+ const { field, recordId, fieldId, renderComponentDefinition } = hoverCell;
6834
+ const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, field._id]);
6835
+ const transformValue = transformCellValue(aiTable, field, cellValue) || {};
6836
+ if (Object.keys(transformValue).length === 0) {
6837
+ return;
6838
+ }
6839
+ const { rowHeight, columnCount, rowCount } = coordinate;
6840
+ const columnIndex = pointPosition.columnIndex;
6841
+ const rowIndex = pointPosition.rowIndex;
6842
+ const x = coordinate.getColumnOffset(columnIndex) + AI_TABLE_OFFSET;
6843
+ const columnWidth = coordinate.getColumnWidth(columnIndex);
6844
+ const y = coordinate.getRowOffset(rowIndex) + AI_TABLE_OFFSET;
6845
+ const { width } = getCellHorizontalPosition({
6846
+ columnWidth,
6847
+ columnIndex,
6848
+ columnCount
6849
+ });
6850
+ const style = {
6851
+ textAlign: DEFAULT_TEXT_ALIGN_LEFT
6852
+ };
6853
+ const textAlign = style.textAlign;
6854
+ const renderX = textAlign === DEFAULT_TEXT_ALIGN_RIGHT
6855
+ ? columnWidth - AI_TABLE_CELL_PADDING + AI_TABLE_OFFSET
6856
+ : AI_TABLE_CELL_PADDING + AI_TABLE_OFFSET;
6857
+ const renderY = 0 - AI_TABLE_OFFSET * 2;
6858
+ const result = {
6859
+ field,
6860
+ aiTable,
6861
+ coordinate,
6862
+ x,
6863
+ y,
6864
+ render: {
6865
+ aiTable,
6866
+ recordId,
6867
+ field,
6868
+ isActive: isSelectedField(field._id, aiTable),
6869
+ x: renderX,
6870
+ y: renderY,
6871
+ columnWidth: width,
6872
+ rowHeight,
6873
+ cellValue,
6874
+ transformValue,
6875
+ style
6876
+ }
6877
+ };
6878
+ return result;
6879
+ });
6880
+ this.hoverCell = computed(() => getHoverCell(this.config().aiTable));
6881
+ }
6882
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableHoverCells, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6883
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableHoverCells, isStandalone: true, selector: "ai-table-hover-cell", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
6884
+ @if (hoverCell()) {
6885
+ <ko-group [config]="groupConfig()">
6886
+ <ng-container *ngComponentOutlet="hoverCell()!.renderComponentDefinition; inputs: { config: hoverCellConfig() }">
6887
+ </ng-container>
6888
+ </ko-group>
6889
+ }
6890
+ `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6891
+ }
6892
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableHoverCells, decorators: [{
6893
+ type: Component,
6894
+ args: [{
6895
+ selector: 'ai-table-hover-cell',
6896
+ template: `
6897
+ @if (hoverCell()) {
6898
+ <ko-group [config]="groupConfig()">
6899
+ <ng-container *ngComponentOutlet="hoverCell()!.renderComponentDefinition; inputs: { config: hoverCellConfig() }">
6900
+ </ng-container>
6901
+ </ko-group>
6902
+ }
6903
+ `,
6904
+ standalone: true,
6905
+ imports: [KoShape, KoContainer, CommonModule],
6906
+ changeDetection: ChangeDetectionStrategy.OnPush
6907
+ }]
6908
+ }] });
6909
+
6654
6910
  Konva.pixelRatio = 2;
6655
6911
  class AITableRenderer {
6656
6912
  constructor() {
@@ -6805,7 +7061,7 @@ class AITableRenderer {
6805
7061
  this.koDblclick.emit(e);
6806
7062
  }
6807
7063
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6808
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableRenderer, isStandalone: true, selector: "ai-table-renderer", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { koMousemove: "koMousemove", koMousedown: "koMousedown", koMouseup: "koMouseup", koContextmenu: "koContextmenu", koWheel: "koWheel", koClick: "koClick", koDblclick: "koDblclick" }, ngImport: i0, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n", dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoStage, selector: "ko-stage", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableColumnHeads, selector: "ai-table-column-heads", inputs: ["config"] }, { kind: "component", type: AITableFrozenColumnHeads, selector: "ai-table-frozen-column-heads", inputs: ["config"] }, { kind: "component", type: AITableCells, selector: "ai-table-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenCells, selector: "ai-table-frozen-cells", inputs: ["config"] }, { kind: "component", type: AITableFrozenPlaceholderCells, selector: "ai-table-frozen-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITablePlaceholderCells, selector: "ai-table-placeholder-cells", inputs: ["config"] }, { kind: "component", type: AITableAddField, selector: "ai-table-add-field", inputs: ["config"] }, { kind: "component", type: AITableHoverRowHeads, selector: "ai-table-hover-row-heads", inputs: ["config"] }, { kind: "component", type: AITableOtherRows, selector: "ai-table-other-rows", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7064
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableRenderer, isStandalone: true, selector: "ai-table-renderer", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { koMousemove: "koMousemove", koMousedown: "koMousedown", koMouseup: "koMouseup", koContextmenu: "koContextmenu", koWheel: "koWheel", koClick: "koClick", koDblclick: "koDblclick" }, ngImport: i0, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n <ai-table-hover-cell [config]=\"cellsConfig()\"></ai-table-hover-cell>\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 <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 </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 }); }
6809
7065
  }
6810
7066
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableRenderer, decorators: [{
6811
7067
  type: Component,
@@ -6818,11 +7074,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
6818
7074
  AITableCells,
6819
7075
  AITableFrozenCells,
6820
7076
  AITableFrozenPlaceholderCells,
7077
+ AITableHoverCells,
6821
7078
  AITablePlaceholderCells,
6822
7079
  AITableAddField,
6823
7080
  AITableHoverRowHeads,
6824
- AITableOtherRows
6825
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n </ko-group>\n\n <ko-group>\n <ai-table-frozen-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-frozen-column-heads>\n </ko-group>\n\n <ko-group [config]=\"commonGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-cells [config]=\"cellsConfig()\"></ai-table-cells>\n </ko-group>\n\n <ko-group [config]=\"offsetXConfig()\">\n <ai-table-column-heads [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-column-heads>\n <ai-table-add-field [config]=\"columnHeadOrAddFieldConfig()\"></ai-table-add-field>\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"attachGroupConfig()\">\n <ko-group [config]=\"offsetConfig()\">\n <ai-table-placeholder-cells [config]=\"cellsConfig()\"></ai-table-placeholder-cells>\n @if (activeCellBorderConfig().activeCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().activeCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n\n <ko-group [config]=\"frozenAttachGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n @if (activeCellBorderConfig().frozenActiveCellBorder) {\n <ko-rect [config]=\"activeCellBorderConfig().frozenActiveCellBorder!\"></ko-rect>\n }\n </ko-group>\n </ko-group>\n </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n" }]
7081
+ AITableOtherRows,
7082
+ AITableCellLink
7083
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ko-stage\n [config]=\"stageConfig()\"\n (koMousemove)=\"stageMousemove($event)\"\n (koMousedown)=\"stageMousedown($event)\"\n (koMouseup)=\"stageMouseup($event)\"\n (koContextmenu)=\"stageContextmenu($event)\"\n (koClick)=\"stageClick($event)\"\n (koDblclick)=\"stageDblclick($event)\"\n>\n <ko-layer>\n <ko-group [config]=\"gridGroupConfig()\">\n <ko-group [config]=\"offsetYConfig()\">\n <ai-table-frozen-cells [config]=\"cellsConfig()\"></ai-table-frozen-cells>\n <ai-table-other-rows [config]=\"cellsConfig()\"></ai-table-other-rows>\n <ai-table-hover-row-heads [config]=\"cellsConfig()\"></ai-table-hover-row-heads>\n <ai-table-frozen-placeholder-cells [config]=\"cellsConfig()\"></ai-table-frozen-placeholder-cells>\n <ai-table-hover-cell [config]=\"cellsConfig()\"></ai-table-hover-cell>\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 <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 </ko-group>\n </ko-layer>\n</ko-stage>\n\n<ng-content></ng-content>\n" }]
6826
7084
  }] });
6827
7085
 
6828
7086
  class AITableGrid extends AITableGridBase {
@@ -7290,5 +7548,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
7290
7548
  * Generated bundle index. Do not edit.
7291
7549
  */
7292
7550
 
7293
- export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsMultiplePipe, AITableFieldSetting, AITableFieldType, AITableFilterOperation, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridSelectionService, AITableMemberType, AITableMouseDownType, AITableQueries, AITableRenderer, AITableRowColumnType, AITableRowType, AITableSelectAllState, AITableSelectOptionStyle, AITableStatType, AI_TABLE_ACTION_COMMON_SIZE, AI_TABLE_BLANK, AI_TABLE_CELL, AI_TABLE_CELL_ACTIVE_BORDER_WIDTH, AI_TABLE_CELL_ADD_ITEM_BUTTON_SIZE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, AI_TABLE_CELL_MAX_ROW_COUNT, AI_TABLE_CELL_MEMBER_ITEM_HEIGHT, AI_TABLE_CELL_MEMBER_ITEM_PADDING, AI_TABLE_CELL_MEMBER_MAX_HEIGHT, AI_TABLE_CELL_MULTI_DOT_RADIUS, AI_TABLE_CELL_MULTI_ITEM_MARGIN_LEFT, AI_TABLE_CELL_MULTI_ITEM_MARGIN_TOP, AI_TABLE_CELL_MULTI_ITEM_MIN_WIDTH, AI_TABLE_CELL_MULTI_PADDING_LEFT, AI_TABLE_CELL_MULTI_PADDING_TOP, AI_TABLE_CELL_PADDING, AI_TABLE_COMMON_FONT_SIZE, AI_TABLE_DEFAULT_COLUMN_WIDTH, AI_TABLE_DOT_RADIUS, AI_TABLE_FIELD_ADD_BUTTON, AI_TABLE_FIELD_ADD_BUTTON_WIDTH, AI_TABLE_FIELD_HEAD, AI_TABLE_FIELD_HEAD_HEIGHT, AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE, AI_TABLE_FIELD_HEAD_MORE, AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX, AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH, AI_TABLE_GRID_FIELD_SERVICE_MAP, AI_TABLE_ICON_COMMON_SIZE, AI_TABLE_MEMBER_AVATAR_SIZE, AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT, AI_TABLE_MEMBER_ITEM_PADDING_RIGHT, AI_TABLE_MIN_TEXT_WIDTH, AI_TABLE_OFFSET, AI_TABLE_OPTION_ITEM_FONT_SIZE, AI_TABLE_OPTION_ITEM_HEIGHT, AI_TABLE_OPTION_ITEM_PADDING, AI_TABLE_OPTION_ITEM_RADIUS, AI_TABLE_PIECE_RADIUS, AI_TABLE_PIECE_WIDTH, AI_TABLE_POPOVER_LEFT_OFFSET, AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS, AI_TABLE_PROGRESS_BAR_HEIGHT, AI_TABLE_PROGRESS_BAR_RADIUS, AI_TABLE_PROGRESS_TEXT_Width, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_HEIGHT, AI_TABLE_ROW_SELECT_CHECKBOX, AI_TABLE_SCROLL_BAR_PADDING, AI_TABLE_TAG_FONT_SIZE, AI_TABLE_TAG_PADDING, AI_TABLE_TEXT_GAP, AbstractEditCellEditor, AddOutlinedPath, Check, Colors, ColumnCalendarFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnSelectFilledPath, ColumnTextFilledPath, Coordinate, DBL_CLICK_EDIT_TYPE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_STYLE, DEFAULT_FONT_WEIGHT, DEFAULT_ICON_SHAPE, DEFAULT_ICON_SIZE, DEFAULT_POINT_POSITION, DEFAULT_SCROLL_STATE, DEFAULT_TEXT_ALIGN_CENTER, DEFAULT_TEXT_ALIGN_LEFT, DEFAULT_TEXT_ALIGN_RIGHT, DEFAULT_TEXT_DECORATION, DEFAULT_TEXT_ELLIPSIS, DEFAULT_TEXT_FILL, DEFAULT_TEXT_LINE_HEIGHT, DEFAULT_TEXT_LISTENING, DEFAULT_TEXT_MAX_CACHE, DEFAULT_TEXT_MAX_HEIGHT, DEFAULT_TEXT_SCALE, DEFAULT_TEXT_TRANSFORMS_ENABLED, DEFAULT_TEXT_VERTICAL_ALIGN_MIDDLE, DEFAULT_TEXT_VERTICAL_ALIGN_TOP, DEFAULT_TEXT_WRAP, DEFAULT_WRAP_TEXT_MAX_ROW, DateCellEditorComponent, DepartmentOutlinedPath, Direction, FONT_SIZE_SM, FieldOptions, GRID_CELL_EDITOR_MAP, IsSelectRecordPipe, LinkCellEditorComponent, MIN_COLUMN_WIDTH, MOUSEOVER_EDIT_TYPE, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, ProgressEditorComponent, RatingCellEditorComponent, RendererContext, RowHeight, SelectCellEditorComponent, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextMeasure, Unchecked, UserPipe, ViewOperationMap, WebOutlinedPath, buildGridData, buildGridLinearRows, castToString, compareNumber, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getDefaultFieldValue, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getHoverEditorBoxOffset, getHoverEditorSpace, getMousePosition, getPlaceHolderCellsConfigs, getTargetName, getTextWidth, getVisibleRangeInfo, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isArrayField, isCellMatchKeywords, isEmpty, isMac, isNumberFiled, isSameFieldOption, isSystemField, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, scrollMax, setMouseStyle, shortIdCreator, shortIdsCreator, stringInclude, textDataCache, transformCellValue, zhIntlCollator };
7551
+ export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsMultiplePipe, AITableFieldSetting, AITableFieldType, AITableFilterOperation, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridSelectionService, AITableMemberType, AITableMouseDownType, AITableQueries, AITableRenderer, AITableRowColumnType, AITableRowType, AITableSelectAllState, AITableSelectOptionStyle, AITableStatType, AI_TABLE_ACTION_COMMON_SIZE, AI_TABLE_BLANK, AI_TABLE_CELL, AI_TABLE_CELL_ACTIVE_BORDER_WIDTH, AI_TABLE_CELL_ADD_ITEM_BUTTON_SIZE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, AI_TABLE_CELL_MAX_ROW_COUNT, AI_TABLE_CELL_MEMBER_ITEM_HEIGHT, AI_TABLE_CELL_MEMBER_ITEM_PADDING, AI_TABLE_CELL_MEMBER_MAX_HEIGHT, AI_TABLE_CELL_MULTI_DOT_RADIUS, AI_TABLE_CELL_MULTI_ITEM_MARGIN_LEFT, AI_TABLE_CELL_MULTI_ITEM_MARGIN_TOP, AI_TABLE_CELL_MULTI_ITEM_MIN_WIDTH, AI_TABLE_CELL_MULTI_PADDING_LEFT, AI_TABLE_CELL_MULTI_PADDING_TOP, AI_TABLE_CELL_PADDING, AI_TABLE_COMMON_FONT_SIZE, AI_TABLE_DEFAULT_COLUMN_WIDTH, AI_TABLE_DOT_RADIUS, AI_TABLE_FIELD_ADD_BUTTON, AI_TABLE_FIELD_ADD_BUTTON_WIDTH, AI_TABLE_FIELD_HEAD, AI_TABLE_FIELD_HEAD_HEIGHT, AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE, AI_TABLE_FIELD_HEAD_MORE, AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX, AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH, AI_TABLE_GRID_FIELD_SERVICE_MAP, AI_TABLE_ICON_COMMON_SIZE, AI_TABLE_MEMBER_AVATAR_SIZE, AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT, AI_TABLE_MEMBER_ITEM_PADDING_RIGHT, AI_TABLE_MIN_TEXT_WIDTH, AI_TABLE_OFFSET, AI_TABLE_OPTION_ITEM_FONT_SIZE, AI_TABLE_OPTION_ITEM_HEIGHT, AI_TABLE_OPTION_ITEM_PADDING, AI_TABLE_OPTION_ITEM_RADIUS, AI_TABLE_PIECE_RADIUS, AI_TABLE_PIECE_WIDTH, AI_TABLE_POPOVER_LEFT_OFFSET, AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS, AI_TABLE_PROGRESS_BAR_HEIGHT, AI_TABLE_PROGRESS_BAR_RADIUS, AI_TABLE_PROGRESS_TEXT_Width, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_HEIGHT, AI_TABLE_ROW_SELECT_CHECKBOX, AI_TABLE_SCROLL_BAR_PADDING, AI_TABLE_TAG_FONT_SIZE, AI_TABLE_TAG_PADDING, AI_TABLE_TEXT_GAP, AbstractEditCellEditor, AddOutlinedPath, Check, Colors, ColumnCalendarFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnSelectFilledPath, ColumnTextFilledPath, Coordinate, DBL_CLICK_EDIT_TYPE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_STYLE, DEFAULT_FONT_WEIGHT, DEFAULT_ICON_SHAPE, DEFAULT_ICON_SIZE, DEFAULT_POINT_POSITION, DEFAULT_SCROLL_STATE, DEFAULT_TEXT_ALIGN_CENTER, DEFAULT_TEXT_ALIGN_LEFT, DEFAULT_TEXT_ALIGN_RIGHT, DEFAULT_TEXT_DECORATION, DEFAULT_TEXT_ELLIPSIS, DEFAULT_TEXT_FILL, DEFAULT_TEXT_LINE_HEIGHT, DEFAULT_TEXT_LISTENING, DEFAULT_TEXT_MAX_CACHE, DEFAULT_TEXT_MAX_HEIGHT, DEFAULT_TEXT_SCALE, DEFAULT_TEXT_TRANSFORMS_ENABLED, DEFAULT_TEXT_VERTICAL_ALIGN_MIDDLE, DEFAULT_TEXT_VERTICAL_ALIGN_TOP, DEFAULT_TEXT_WRAP, DEFAULT_WRAP_TEXT_MAX_ROW, DateCellEditorComponent, DepartmentOutlinedPath, Direction, FONT_SIZE_SM, FieldOptions, GRID_CELL_EDITOR_MAP, IsSelectRecordPipe, LinkCellEditorComponent, MIN_COLUMN_WIDTH, MOUSEOVER_EDIT_TYPE, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, ProgressEditorComponent, RatingCellEditorComponent, RendererContext, RowHeight, SelectCellEditorComponent, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextMeasure, Unchecked, UserPipe, ViewOperationMap, WebOutlinedPath, buildGridData, buildGridLinearRows, castToString, compareNumber, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getDefaultFieldValue, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getHoverCell, getHoverEditorBoxOffset, getHoverEditorSpace, getMousePosition, getPlaceHolderCellsConfigs, getTargetName, getTextWidth, getVisibleRangeInfo, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isArrayField, isCellMatchKeywords, isEmpty, isMac, isNumberFiled, isSameFieldOption, isSelectedField, isSystemField, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, scrollMax, setMouseStyle, shortIdCreator, shortIdsCreator, stringInclude, textDataCache, transformCellValue, zhIntlCollator };
7294
7552
  //# sourceMappingURL=ai-table-grid.mjs.map