@ai-table/grid 0.0.43 → 0.0.45

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 (119) hide show
  1. package/angular-konva/interfaces/event-object.d.ts +4 -0
  2. package/angular-konva/interfaces/event-object.d.ts.map +1 -1
  3. package/components/cell-editors/date/date-editor.component.d.ts +1 -0
  4. package/components/cell-editors/date/date-editor.component.d.ts.map +1 -1
  5. package/components/cell-editors/link/edit-link/edit-link.component.d.ts +13 -3
  6. package/components/cell-editors/link/edit-link/edit-link.component.d.ts.map +1 -1
  7. package/components/cell-editors/link/link-editor.component.d.ts +1 -0
  8. package/components/cell-editors/link/link-editor.component.d.ts.map +1 -1
  9. package/components/drag/drag.component.d.ts +10 -1
  10. package/components/drag/drag.component.d.ts.map +1 -1
  11. package/components/drag/drag.component.scss +1 -1
  12. package/components/field-menu/field-menu.component.d.ts +3 -2
  13. package/components/field-menu/field-menu.component.d.ts.map +1 -1
  14. package/components/field-setting/field-setting.component.d.ts +17 -3
  15. package/components/field-setting/field-setting.component.d.ts.map +1 -1
  16. package/constants/grid.d.ts.map +1 -1
  17. package/constants/table.d.ts +5 -1
  18. package/constants/table.d.ts.map +1 -1
  19. package/core/constants/field.d.ts +2 -2
  20. package/core/constants/field.d.ts.map +1 -1
  21. package/core/types/ai-table.d.ts +2 -0
  22. package/core/types/ai-table.d.ts.map +1 -1
  23. package/core/types/core.d.ts +4 -4
  24. package/core/types/core.d.ts.map +1 -1
  25. package/core/utils/common.d.ts +1 -0
  26. package/core/utils/common.d.ts.map +1 -1
  27. package/core/utils/field.d.ts +1 -1
  28. package/core/utils/field.d.ts.map +1 -1
  29. package/core/utils/{shoft-id.d.ts → short-id.d.ts} +1 -1
  30. package/core/utils/{shoft-id.d.ts.map → short-id.d.ts.map} +1 -1
  31. package/esm2022/angular-konva/interfaces/event-object.mjs +1 -1
  32. package/esm2022/components/cell-editors/date/date-editor.component.mjs +9 -3
  33. package/esm2022/components/cell-editors/link/edit-link/edit-link.component.mjs +27 -12
  34. package/esm2022/components/cell-editors/link/link-editor.component.mjs +12 -8
  35. package/esm2022/components/drag/drag.component.mjs +107 -79
  36. package/esm2022/components/field-menu/field-menu.component.mjs +9 -3
  37. package/esm2022/components/field-setting/field-setting.component.mjs +28 -14
  38. package/esm2022/constants/grid.mjs +1 -2
  39. package/esm2022/constants/table.mjs +6 -2
  40. package/esm2022/core/constants/field.mjs +95 -95
  41. package/esm2022/core/types/ai-table.mjs +1 -1
  42. package/esm2022/core/types/core.mjs +1 -2
  43. package/esm2022/core/utils/common.mjs +13 -1
  44. package/esm2022/core/utils/field.mjs +13 -8
  45. package/esm2022/core/utils/id-creator.mjs +2 -2
  46. package/esm2022/core/utils/{shoft-id.mjs → short-id.mjs} +1 -1
  47. package/esm2022/grid-base.component.mjs +14 -4
  48. package/esm2022/grid.component.mjs +54 -29
  49. package/esm2022/renderer/components/action-icon.component.mjs +117 -0
  50. package/esm2022/renderer/components/cells/attachment.component.mjs +117 -0
  51. package/esm2022/renderer/components/cells/index.mjs +3 -1
  52. package/esm2022/renderer/components/cells/link.component.mjs +2 -2
  53. package/esm2022/renderer/components/hover-cell.component.mjs +7 -7
  54. package/esm2022/renderer/creations/create-active-cell-border.mjs +1 -2
  55. package/esm2022/renderer/creations/create-heads.mjs +3 -2
  56. package/esm2022/renderer/drawers/cell-drawer.mjs +4 -7
  57. package/esm2022/types/cell.mjs +1 -1
  58. package/esm2022/types/component-config.mjs +1 -1
  59. package/esm2022/types/field.mjs +1 -1
  60. package/esm2022/types/grid.mjs +1 -1
  61. package/esm2022/utils/build.mjs +5 -4
  62. package/esm2022/utils/cell.mjs +3 -3
  63. package/esm2022/utils/clipboard/paste.mjs +6 -4
  64. package/esm2022/utils/common.mjs +6 -5
  65. package/esm2022/utils/field/model/date.mjs +6 -12
  66. package/esm2022/utils/field/model/progress.mjs +11 -4
  67. package/esm2022/utils/file.mjs +1 -93
  68. package/esm2022/utils/hover-cell.mjs +1 -8
  69. package/esm2022/utils/i18n.mjs +85 -0
  70. package/esm2022/utils/index.mjs +2 -1
  71. package/esm2022/utils/position.mjs +3 -3
  72. package/esm2022/utils/visible-range.mjs +3 -3
  73. package/fesm2022/ai-table-grid.mjs +1762 -1510
  74. package/fesm2022/ai-table-grid.mjs.map +1 -1
  75. package/grid-base.component.d.ts +7 -2
  76. package/grid-base.component.d.ts.map +1 -1
  77. package/grid.component.d.ts.map +1 -1
  78. package/package.json +1 -1
  79. package/renderer/components/action-icon.component.d.ts +47 -0
  80. package/renderer/components/action-icon.component.d.ts.map +1 -0
  81. package/renderer/components/cells/attachment.component.d.ts +16 -0
  82. package/renderer/components/cells/attachment.component.d.ts.map +1 -0
  83. package/renderer/components/cells/index.d.ts +1 -0
  84. package/renderer/components/cells/index.d.ts.map +1 -1
  85. package/renderer/creations/create-active-cell-border.d.ts.map +1 -1
  86. package/renderer/creations/create-heads.d.ts.map +1 -1
  87. package/renderer/drawers/cell-drawer.d.ts.map +1 -1
  88. package/types/cell.d.ts +1 -0
  89. package/types/cell.d.ts.map +1 -1
  90. package/types/component-config.d.ts +13 -1
  91. package/types/component-config.d.ts.map +1 -1
  92. package/types/field.d.ts +1 -1
  93. package/types/field.d.ts.map +1 -1
  94. package/types/grid.d.ts +1 -1
  95. package/types/grid.d.ts.map +1 -1
  96. package/utils/build.d.ts +2 -2
  97. package/utils/build.d.ts.map +1 -1
  98. package/utils/cell.d.ts +1 -1
  99. package/utils/cell.d.ts.map +1 -1
  100. package/utils/clipboard/paste.d.ts +2 -2
  101. package/utils/clipboard/paste.d.ts.map +1 -1
  102. package/utils/common.d.ts +1 -1
  103. package/utils/common.d.ts.map +1 -1
  104. package/utils/field/model/date.d.ts.map +1 -1
  105. package/utils/field/model/progress.d.ts.map +1 -1
  106. package/utils/file.d.ts +0 -9
  107. package/utils/file.d.ts.map +1 -1
  108. package/utils/hover-cell.d.ts.map +1 -1
  109. package/utils/i18n.d.ts +39 -0
  110. package/utils/i18n.d.ts.map +1 -0
  111. package/utils/index.d.ts +1 -0
  112. package/utils/index.d.ts.map +1 -1
  113. package/utils/position.d.ts +2 -2
  114. package/utils/position.d.ts.map +1 -1
  115. package/utils/visible-range.d.ts +2 -2
  116. package/utils/visible-range.d.ts.map +1 -1
  117. package/esm2022/utils/icon.mjs +0 -48
  118. package/utils/icon.d.ts +0 -19
  119. package/utils/icon.d.ts.map +0 -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, input, Renderer2, Pipe, model, booleanAttribute, Injectable, InjectionToken, effect, DestroyRef, NgZone, ViewContainerRef, viewChild, afterNextRender, untracked } from '@angular/core';
2
+ import { signal, computed, output, inject, ElementRef, Component, ChangeDetectionStrategy, Input, input, EventEmitter, Output, ChangeDetectorRef, ViewChild, HostListener, Renderer2, Pipe, 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';
@@ -152,7 +152,6 @@ var AITableFieldType;
152
152
  AITableFieldType["number"] = "number";
153
153
  AITableFieldType["date"] = "date";
154
154
  AITableFieldType["member"] = "member";
155
- // cascadeSelect = 'cascade_select', // 包含单选和多选,参数复杂后续再进行设计
156
155
  AITableFieldType["progress"] = "progress";
157
156
  AITableFieldType["rate"] = "rate";
158
157
  AITableFieldType["link"] = "link";
@@ -203,105 +202,189 @@ var DragType;
203
202
  DragType["none"] = "none";
204
203
  })(DragType || (DragType = {}));
205
204
 
205
+ var AITableGridI18nKey;
206
+ (function (AITableGridI18nKey) {
207
+ AITableGridI18nKey["dataPickerPlaceholder"] = "dataPickerPlaceholder";
208
+ AITableGridI18nKey["linkTooltip"] = "linkTooltip";
209
+ AITableGridI18nKey["invalidLinkFormat"] = "invalidLinkFormat";
210
+ AITableGridI18nKey["linkRequired"] = "linkRequired";
211
+ AITableGridI18nKey["linkText"] = "linkText";
212
+ AITableGridI18nKey["linkUrl"] = "linkUrl";
213
+ AITableGridI18nKey["inputText"] = "inputText";
214
+ AITableGridI18nKey["inputUrl"] = "inputUrl";
215
+ AITableGridI18nKey["fieldColumnName"] = "fieldColumnName";
216
+ AITableGridI18nKey["fieldColumnNamePlaceholder"] = "fieldColumnNamePlaceholder";
217
+ AITableGridI18nKey["fieldType"] = "fieldType";
218
+ AITableGridI18nKey["allowMultipleMembers"] = "allowMultipleMembers";
219
+ AITableGridI18nKey["cancel"] = "cancel";
220
+ AITableGridI18nKey["apply"] = "apply";
221
+ AITableGridI18nKey["fieldNameRequired"] = "fieldNameRequired";
222
+ AITableGridI18nKey["fieldNameDuplicate"] = "fieldNameDuplicate";
223
+ AITableGridI18nKey["confirm"] = "confirm";
224
+ AITableGridI18nKey["copiedCells"] = "copiedCells";
225
+ AITableGridI18nKey["invalidPasteContent"] = "invalidPasteContent";
226
+ AITableGridI18nKey["fieldTypeText"] = "fieldTypeText";
227
+ AITableGridI18nKey["fieldTypeSelect"] = "fieldTypeSelect";
228
+ AITableGridI18nKey["fieldTypeMultiSelect"] = "fieldTypeMultiSelect";
229
+ AITableGridI18nKey["fieldTypeNumber"] = "fieldTypeNumber";
230
+ AITableGridI18nKey["fieldTypeDate"] = "fieldTypeDate";
231
+ AITableGridI18nKey["fieldTypeMember"] = "fieldTypeMember";
232
+ AITableGridI18nKey["fieldTypeProgress"] = "fieldTypeProgress";
233
+ AITableGridI18nKey["fieldTypeRate"] = "fieldTypeRate";
234
+ AITableGridI18nKey["fieldTypeLink"] = "fieldTypeLink";
235
+ AITableGridI18nKey["fieldTypeAttachment"] = "fieldTypeAttachment";
236
+ AITableGridI18nKey["fieldTypeCreatedBy"] = "fieldTypeCreatedBy";
237
+ AITableGridI18nKey["fieldTypeCreatedAt"] = "fieldTypeCreatedAt";
238
+ AITableGridI18nKey["fieldTypeUpdatedBy"] = "fieldTypeUpdatedBy";
239
+ AITableGridI18nKey["fieldTypeUpdatedAt"] = "fieldTypeUpdatedAt";
240
+ })(AITableGridI18nKey || (AITableGridI18nKey = {}));
241
+ const AITableI18nText = {
242
+ [AITableGridI18nKey.dataPickerPlaceholder]: '选择日期',
243
+ [AITableGridI18nKey.linkTooltip]: '链接',
244
+ [AITableGridI18nKey.invalidLinkFormat]: '链接格式不正确',
245
+ [AITableGridI18nKey.linkRequired]: '链接不能为空',
246
+ [AITableGridI18nKey.linkText]: '文本',
247
+ [AITableGridI18nKey.linkUrl]: '链接',
248
+ [AITableGridI18nKey.inputText]: '输入文本',
249
+ [AITableGridI18nKey.inputUrl]: '输入链接',
250
+ [AITableGridI18nKey.fieldColumnName]: '表格列名',
251
+ [AITableGridI18nKey.fieldColumnNamePlaceholder]: '输入列名称',
252
+ [AITableGridI18nKey.fieldType]: '列类型',
253
+ [AITableGridI18nKey.allowMultipleMembers]: '允许选择多个成员',
254
+ [AITableGridI18nKey.cancel]: '取消',
255
+ [AITableGridI18nKey.apply]: '应用',
256
+ [AITableGridI18nKey.fieldNameRequired]: '列名不能为空',
257
+ [AITableGridI18nKey.fieldNameDuplicate]: '列名已存在',
258
+ [AITableGridI18nKey.confirm]: '确定',
259
+ [AITableGridI18nKey.copiedCells]: '已复制 {count} 个单元格',
260
+ [AITableGridI18nKey.invalidPasteContent]: '粘贴内容不符合当前类型', // 新增
261
+ [AITableGridI18nKey.fieldTypeText]: '单行文本',
262
+ [AITableGridI18nKey.fieldTypeSelect]: '单选',
263
+ [AITableGridI18nKey.fieldTypeMultiSelect]: '多选',
264
+ [AITableGridI18nKey.fieldTypeNumber]: '数字',
265
+ [AITableGridI18nKey.fieldTypeDate]: '日期',
266
+ [AITableGridI18nKey.fieldTypeMember]: '成员',
267
+ [AITableGridI18nKey.fieldTypeProgress]: '进度',
268
+ [AITableGridI18nKey.fieldTypeRate]: '评分',
269
+ [AITableGridI18nKey.fieldTypeLink]: '链接',
270
+ [AITableGridI18nKey.fieldTypeAttachment]: '附件',
271
+ [AITableGridI18nKey.fieldTypeCreatedBy]: '创建人',
272
+ [AITableGridI18nKey.fieldTypeCreatedAt]: '创建时间',
273
+ [AITableGridI18nKey.fieldTypeUpdatedBy]: '更新人',
274
+ [AITableGridI18nKey.fieldTypeUpdatedAt]: '更新时间'
275
+ };
276
+ const getDefaultI18nTextByKey = (key) => {
277
+ return AITableI18nText[key] || key;
278
+ };
279
+ const getI18nTextByKey = (aiTable, key) => {
280
+ if (aiTable.getI18nTextByKey) {
281
+ const customText = aiTable.getI18nTextByKey(key);
282
+ if (customText) {
283
+ return customText;
284
+ }
285
+ }
286
+ const defaultText = getDefaultI18nTextByKey(key);
287
+ return defaultText;
288
+ };
289
+
206
290
  const AI_TABLE_FIELD_MINI_WIDTH = 140;
207
291
  const AI_TABLE_FIELD_MIN_WIDTH = 160;
208
292
  const AI_TABLE_FIELD_MIDDLE_WIDTH = 200;
209
293
  const AI_TABLE_FIELD_MAX_WIDTH = 300;
210
- const FieldOptions = [
211
- {
212
- type: AITableFieldType.text,
213
- name: '单行文本',
214
- icon: 'font',
215
- width: AI_TABLE_FIELD_MAX_WIDTH
216
- },
217
- // 多行文本
218
- {
219
- type: AITableFieldType.select,
220
- name: '单选',
221
- icon: 'check-circle',
222
- width: AI_TABLE_FIELD_MIN_WIDTH
223
- },
224
- {
225
- type: AITableFieldType.select,
226
- name: '多选',
227
- icon: 'list-check',
228
- width: AI_TABLE_FIELD_MIDDLE_WIDTH,
229
- settings: {
230
- is_multiple: true
231
- }
232
- },
233
- {
234
- type: AITableFieldType.number,
235
- name: '数字',
236
- icon: 'hashtag',
237
- width: AI_TABLE_FIELD_MINI_WIDTH
238
- },
239
- {
240
- type: AITableFieldType.date,
241
- name: '日期',
242
- icon: 'calendar',
243
- width: AI_TABLE_FIELD_MIDDLE_WIDTH
244
- },
245
- {
246
- type: AITableFieldType.member,
247
- name: '成员',
248
- icon: 'user',
249
- width: AI_TABLE_FIELD_MIN_WIDTH,
250
- settings: {
251
- is_multiple: false
252
- }
253
- },
254
- // 级联单选
255
- // 级联多选
256
- {
257
- type: AITableFieldType.progress,
258
- name: '进度',
259
- icon: 'progress',
260
- width: AI_TABLE_FIELD_MIDDLE_WIDTH
261
- },
262
- {
263
- type: AITableFieldType.rate,
264
- name: '评分',
265
- icon: 'star-circle',
266
- width: AI_TABLE_FIELD_MIN_WIDTH
267
- },
268
- {
269
- type: AITableFieldType.link,
270
- name: '链接',
271
- icon: 'link-insert',
272
- width: AI_TABLE_FIELD_MIDDLE_WIDTH
273
- },
274
- {
275
- type: AITableFieldType.attachment,
276
- name: '附件',
277
- icon: 'attachment',
278
- width: AI_TABLE_FIELD_MIDDLE_WIDTH
279
- },
280
- {
281
- type: AITableFieldType.createdBy,
282
- name: '创建人',
283
- icon: 'user',
284
- width: AI_TABLE_FIELD_MIN_WIDTH
285
- },
286
- {
287
- type: AITableFieldType.createdAt,
288
- name: '创建时间',
289
- icon: 'calendar',
290
- width: AI_TABLE_FIELD_MIDDLE_WIDTH
291
- },
292
- {
293
- type: AITableFieldType.updatedBy,
294
- name: '更新人',
295
- icon: 'user',
296
- width: AI_TABLE_FIELD_MIN_WIDTH
297
- },
298
- {
299
- type: AITableFieldType.updatedAt,
300
- name: '更新时间',
301
- icon: 'calendar',
302
- width: AI_TABLE_FIELD_MIDDLE_WIDTH
303
- }
304
- ];
294
+ function getFieldOptions(aiTable) {
295
+ return [
296
+ {
297
+ type: AITableFieldType.text,
298
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeText),
299
+ icon: 'font',
300
+ width: AI_TABLE_FIELD_MAX_WIDTH
301
+ },
302
+ {
303
+ type: AITableFieldType.select,
304
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeSelect),
305
+ icon: 'check-circle',
306
+ width: AI_TABLE_FIELD_MIN_WIDTH
307
+ },
308
+ {
309
+ type: AITableFieldType.select,
310
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeMultiSelect),
311
+ icon: 'list-check',
312
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH,
313
+ settings: {
314
+ is_multiple: true
315
+ }
316
+ },
317
+ {
318
+ type: AITableFieldType.number,
319
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeNumber),
320
+ icon: 'hashtag',
321
+ width: AI_TABLE_FIELD_MINI_WIDTH
322
+ },
323
+ {
324
+ type: AITableFieldType.date,
325
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeDate),
326
+ icon: 'calendar',
327
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH
328
+ },
329
+ {
330
+ type: AITableFieldType.member,
331
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeMember),
332
+ icon: 'user',
333
+ width: AI_TABLE_FIELD_MIN_WIDTH,
334
+ settings: {
335
+ is_multiple: false
336
+ }
337
+ },
338
+ {
339
+ type: AITableFieldType.progress,
340
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeProgress),
341
+ icon: 'progress',
342
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH
343
+ },
344
+ {
345
+ type: AITableFieldType.rate,
346
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeRate),
347
+ icon: 'star-circle',
348
+ width: AI_TABLE_FIELD_MIN_WIDTH
349
+ },
350
+ {
351
+ type: AITableFieldType.link,
352
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeLink),
353
+ icon: 'link-insert',
354
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH
355
+ },
356
+ {
357
+ type: AITableFieldType.attachment,
358
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeAttachment),
359
+ icon: 'attachment',
360
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH
361
+ },
362
+ {
363
+ type: AITableFieldType.createdBy,
364
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeCreatedBy),
365
+ icon: 'user',
366
+ width: AI_TABLE_FIELD_MIN_WIDTH
367
+ },
368
+ {
369
+ type: AITableFieldType.createdAt,
370
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeCreatedAt),
371
+ icon: 'calendar',
372
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH
373
+ },
374
+ {
375
+ type: AITableFieldType.updatedBy,
376
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeUpdatedBy),
377
+ icon: 'user',
378
+ width: AI_TABLE_FIELD_MIN_WIDTH
379
+ },
380
+ {
381
+ type: AITableFieldType.updatedAt,
382
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeUpdatedAt),
383
+ icon: 'calendar',
384
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH
385
+ }
386
+ ];
387
+ }
305
388
 
306
389
  var AITableAvatarSize;
307
390
  (function (AITableAvatarSize) {
@@ -674,6 +757,49 @@ function shortIdsCreator(count) {
674
757
  return shortId(undefined, 8, count);
675
758
  }
676
759
 
760
+ function createAITable(records, fields, gridData) {
761
+ const aiTable = {
762
+ records,
763
+ fields,
764
+ gridData,
765
+ selection: signal({
766
+ selectedRecords: new Set(),
767
+ selectedFields: new Set(),
768
+ selectedCells: new Set(),
769
+ activeCell: null,
770
+ selectAllState: AITableSelectAllState.none
771
+ }),
772
+ keywordsMatchedCells: signal(new Set()),
773
+ recordsMap: computed(() => {
774
+ return records().reduce((object, item) => {
775
+ object[item._id] = item;
776
+ return object;
777
+ }, {});
778
+ }),
779
+ fieldsMap: computed(() => {
780
+ return fields().reduce((object, item) => {
781
+ object[item._id] = item;
782
+ return object;
783
+ }, {});
784
+ }),
785
+ recordsWillHidden: signal([]),
786
+ recordsWillMove: signal([])
787
+ };
788
+ return aiTable;
789
+ }
790
+ function generateNewName(existNames, count, name) {
791
+ let newName = name;
792
+ let suffix = count;
793
+ if (count > 1) {
794
+ newName = `${name} ${suffix}`;
795
+ }
796
+ while (existNames.includes(newName)) {
797
+ suffix++;
798
+ newName = `${name} ${suffix}`;
799
+ }
800
+ return newName;
801
+ }
802
+
677
803
  const isArrayField = (field) => {
678
804
  return [
679
805
  AITableFieldType.member,
@@ -699,17 +825,20 @@ function getDefaultFieldValue(field) {
699
825
  return '';
700
826
  }
701
827
  function createDefaultFieldName(aiTable, field) {
702
- const fieldOption = getFieldOptionByField(field);
828
+ const fieldOption = getFieldOptionByField(aiTable, field);
703
829
  if (fieldOption) {
830
+ const allNames = aiTable.fields().map((item) => item.name);
704
831
  const count = aiTable.fields().filter((item) => {
705
832
  return isSameFieldOption(field, item);
706
833
  }).length;
707
- return count === 0 ? fieldOption.name : fieldOption.name + ' ' + count;
834
+ return generateNewName(allNames, count, fieldOption.name);
708
835
  }
709
- return FieldOptions[0].name;
836
+ const fieldOptions = getFieldOptions(aiTable);
837
+ return fieldOptions[0].name;
710
838
  }
711
- function getFieldOptionByField(field) {
712
- let fieldOption = FieldOptions.find((item) => isSameFieldOption(item, field));
839
+ function getFieldOptionByField(aiTable, field) {
840
+ const fieldOptions = getFieldOptions(aiTable);
841
+ let fieldOption = fieldOptions.find((item) => isSameFieldOption(item, field));
713
842
  if (fieldOption && field.type === AITableFieldType.member && field.settings?.is_multiple) {
714
843
  fieldOption.width = AI_TABLE_FIELD_MIDDLE_WIDTH;
715
844
  }
@@ -722,41 +851,11 @@ function isSameFieldOption(fieldOption, field) {
722
851
  : true));
723
852
  }
724
853
  function createDefaultField(aiTable, type = AITableFieldType.text) {
725
- const fieldOption = FieldOptions.find((item) => item.type === type);
854
+ const fieldOptions = getFieldOptions(aiTable);
855
+ const fieldOption = fieldOptions.find((item) => item.type === type);
726
856
  return { _id: idCreator(), type, name: createDefaultFieldName(aiTable, fieldOption) };
727
857
  }
728
858
 
729
- function createAITable(records, fields, gridData) {
730
- const aiTable = {
731
- records,
732
- fields,
733
- gridData,
734
- selection: signal({
735
- selectedRecords: new Set(),
736
- selectedFields: new Set(),
737
- selectedCells: new Set(),
738
- activeCell: null,
739
- selectAllState: AITableSelectAllState.none
740
- }),
741
- keywordsMatchedCells: signal(new Set()),
742
- recordsMap: computed(() => {
743
- return records().reduce((object, item) => {
744
- object[item._id] = item;
745
- return object;
746
- }, {});
747
- }),
748
- fieldsMap: computed(() => {
749
- return fields().reduce((object, item) => {
750
- object[item._id] = item;
751
- return object;
752
- }, {});
753
- }),
754
- recordsWillHidden: signal([]),
755
- recordsWillMove: signal([])
756
- };
757
- return aiTable;
758
- }
759
-
760
859
  function getFieldValue(record, field) {
761
860
  if (isSystemField(field)) {
762
861
  return getSystemFieldValue(record, field.type);
@@ -917,6 +1016,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
917
1016
  }] } });
918
1017
 
919
1018
  class DateCellEditorComponent extends AbstractEditCellEditor {
1019
+ constructor() {
1020
+ super(...arguments);
1021
+ this.placeholder = '';
1022
+ }
920
1023
  ngOnInit() {
921
1024
  this.modelValue = computed(() => {
922
1025
  const value = AITableQueries.getFieldValue(this.aiTable, [this.record()._id, this.field()._id]);
@@ -927,6 +1030,7 @@ class DateCellEditorComponent extends AbstractEditCellEditor {
927
1030
  }
928
1031
  return value;
929
1032
  })();
1033
+ this.placeholder = getI18nTextByKey(this.aiTable, AITableGridI18nKey.dataPickerPlaceholder);
930
1034
  }
931
1035
  updateValue(value) {
932
1036
  this.updateFieldValue.emit({
@@ -945,7 +1049,7 @@ class DateCellEditorComponent extends AbstractEditCellEditor {
945
1049
  <thy-date-picker
946
1050
  class="h-100"
947
1051
  thyTimestampPrecision="seconds"
948
- thyPlaceHolder="选择日期"
1052
+ [thyPlaceHolder]="placeholder"
949
1053
  [ngModel]="modelValue.timestamp"
950
1054
  (ngModelChange)="updateValue($event)"
951
1055
  (thyOpenChange)="thyOpenChange($event)"
@@ -967,7 +1071,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
967
1071
  <thy-date-picker
968
1072
  class="h-100"
969
1073
  thyTimestampPrecision="seconds"
970
- thyPlaceHolder="选择日期"
1074
+ [thyPlaceHolder]="placeholder"
971
1075
  [ngModel]="modelValue.timestamp"
972
1076
  (ngModelChange)="updateValue($event)"
973
1077
  (thyOpenChange)="thyOpenChange($event)"
@@ -998,23 +1102,37 @@ class LinkEditComponent {
998
1102
  this.thyPopoverRef = thyPopoverRef;
999
1103
  this.url = '';
1000
1104
  this.text = '';
1105
+ this.aiTable = input();
1001
1106
  this.confirm = new EventEmitter();
1002
1107
  this.URLRegex = LINK_URL_REGEX;
1003
- this.validatorConfig = {
1004
- validationMessages: {
1005
- url: {
1006
- pattern: '链接格式不正确'
1108
+ this.i18nTexts = computed(() => {
1109
+ return {
1110
+ linkText: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.linkText),
1111
+ textPlaceholder: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.inputText),
1112
+ urlLabel: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.linkUrl),
1113
+ urlPlaceholder: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.inputUrl),
1114
+ cancel: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.cancel),
1115
+ apply: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.apply)
1116
+ };
1117
+ });
1118
+ this.validatorConfig = computed(() => {
1119
+ return {
1120
+ validationMessages: {
1121
+ url: {
1122
+ pattern: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.invalidLinkFormat)
1123
+ }
1007
1124
  }
1008
- }
1009
- };
1125
+ };
1126
+ });
1127
+ }
1128
+ ngOnInit() {
1010
1129
  }
1011
- ngOnInit() { }
1012
1130
  close() {
1013
1131
  this.thyPopoverRef.close();
1014
1132
  }
1015
1133
  apply(form) {
1016
1134
  if (this.text && !this.url) {
1017
- form.validator.setElementErrorMessage('url', '链接不能为空');
1135
+ form.validator.setElementErrorMessage('url', getI18nTextByKey(this.aiTable(), AITableGridI18nKey.linkRequired));
1018
1136
  return;
1019
1137
  }
1020
1138
  this.close();
@@ -1024,7 +1142,7 @@ class LinkEditComponent {
1024
1142
  this.confirm.emit(link);
1025
1143
  }
1026
1144
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LinkEditComponent, deps: [{ token: i1$1.ThyPopoverRef }], target: i0.ɵɵFactoryTarget.Component }); }
1027
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: LinkEditComponent, isStandalone: true, selector: "link-edit", inputs: { url: "url", text: "text" }, outputs: { confirm: "confirm" }, ngImport: i0, template: "<form\n thyLayout=\"vertical\"\n thyStopPropagation\n thyForm\n #linkForm=\"thyForm\"\n [thyFormValidatorConfig]=\"validatorConfig\"\n name=\"linkForm\"\n class=\"p-5\"\n>\n <thy-form-group thyLabelText=\"\u6587\u672C\">\n <input thyInput placeholder=\"\u8F93\u5165\u6587\u672C\" name=\"text\" [(ngModel)]=\"text\" thyAutofocus type=\"text\" />\n </thy-form-group>\n <thy-form-group thyLabelText=\"\u94FE\u63A5\">\n <input name=\"url\" thyInput placeholder=\"\u8F93\u5165\u94FE\u63A5\" [pattern]=\"URLRegex\" type=\"text\" [(ngModel)]=\"url\" />\n </thy-form-group>\n <thy-form-group-footer thyAlign=\"right\">\n <div class=\"btn-pair\">\n <button thyStopPropagation thyButton=\"link-secondary\" thySize=\"sm\" (click)=\"close()\">\u53D6\u6D88</button>\n <button thyStopPropagation thyButton=\"primary\" thySize=\"sm\" (thyFormSubmit)=\"apply(linkForm)\">\u5E94\u7528</button>\n </div>\n </thy-form-group-footer>\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "directive", type: ThyInputDirective, selector: "input[thyInput], select[thyInput], textarea[thyInput]", inputs: ["thySize"], exportAs: ["thyInput"] }, { kind: "directive", type: ThyAutofocusDirective, selector: "input[thyAutofocus],textarea[thyAutofocus]", inputs: ["thyAutofocus", "thyAutoSelect"] }, { kind: "component", type: ThyButton, selector: "thy-button,[thy-button],[thyButton]", inputs: ["thyButton", "thyType", "thyLoading", "thyLoadingText", "thySize", "thyIcon", "thyBlock"] }, { kind: "directive", type: ThyFormSubmitDirective, selector: "[thyFormSubmit],[thy-form-submit]", outputs: ["thyFormSubmit"] }, { kind: "ngmodule", type: ThyFormModule }, { kind: "directive", type: i2.ThyFormDirective, selector: "[thyForm],[thy-form]", inputs: ["thyLayout", "thyEnterKeyMode", "thyFormValidatorConfig"], exportAs: ["thyForm"] }, { kind: "component", type: i2.ThyFormGroup, selector: "thy-form-group", inputs: ["thyLabelText", "thyLabelTextTranslateKey", "thyLabelRequired", "thyLabelPaddingTopClear", "thyFeedbackIcon", "thyTipsMode", "thyTips", "thyTipsTranslateKey", "thyRowFill"] }, { kind: "component", type: i2.ThyFormGroupFooter, selector: "thy-form-group-footer", inputs: ["thyAlign"] }] }); }
1145
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: LinkEditComponent, isStandalone: true, selector: "link-edit", inputs: { url: { classPropertyName: "url", publicName: "url", isSignal: false, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: false, isRequired: false, transformFunction: null }, aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirm: "confirm" }, ngImport: i0, template: "<form\n thyLayout=\"vertical\"\n thyStopPropagation\n thyForm\n #linkForm=\"thyForm\"\n [thyFormValidatorConfig]=\"validatorConfig()\"\n name=\"linkForm\"\n class=\"p-5\"\n>\n <thy-form-group [thyLabelText]=\"i18nTexts().linkText\">\n <input thyInput [placeholder]=\"i18nTexts().textPlaceholder\" />\n </thy-form-group>\n <thy-form-group [thyLabelText]=\"i18nTexts().urlLabel\">\n <input name=\"url\" thyInput [placeholder]=\"i18nTexts().urlPlaceholder\" [pattern]=\"URLRegex\" type=\"text\" [(ngModel)]=\"url\" />\n </thy-form-group>\n <thy-form-group-footer thyAlign=\"right\">\n <div class=\"btn-pair\">\n <button thyStopPropagation thyButton=\"link-secondary\" thySize=\"sm\" (click)=\"close()\">{{i18nTexts().cancel}}</button>\n <button thyStopPropagation thyButton=\"primary\" thySize=\"sm\" (thyFormSubmit)=\"apply(linkForm)\">{{i18nTexts().apply}}</button>\n </div>\n </thy-form-group-footer>\n</form>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "directive", type: ThyInputDirective, selector: "input[thyInput], select[thyInput], textarea[thyInput]", inputs: ["thySize"], exportAs: ["thyInput"] }, { kind: "component", type: ThyButton, selector: "thy-button,[thy-button],[thyButton]", inputs: ["thyButton", "thyType", "thyLoading", "thyLoadingText", "thySize", "thyIcon", "thyBlock"] }, { kind: "directive", type: ThyFormSubmitDirective, selector: "[thyFormSubmit],[thy-form-submit]", outputs: ["thyFormSubmit"] }, { kind: "ngmodule", type: ThyFormModule }, { kind: "directive", type: i2.ThyFormDirective, selector: "[thyForm],[thy-form]", inputs: ["thyLayout", "thyEnterKeyMode", "thyFormValidatorConfig"], exportAs: ["thyForm"] }, { kind: "component", type: i2.ThyFormGroup, selector: "thy-form-group", inputs: ["thyLabelText", "thyLabelTextTranslateKey", "thyLabelRequired", "thyLabelPaddingTopClear", "thyFeedbackIcon", "thyTipsMode", "thyTips", "thyTipsTranslateKey", "thyRowFill"] }, { kind: "component", type: i2.ThyFormGroupFooter, selector: "thy-form-group-footer", inputs: ["thyAlign"] }] }); }
1028
1146
  }
1029
1147
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LinkEditComponent, decorators: [{
1030
1148
  type: Component,
@@ -1036,7 +1154,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1036
1154
  ThyButton,
1037
1155
  ThyFormSubmitDirective,
1038
1156
  ThyFormModule
1039
- ], template: "<form\n thyLayout=\"vertical\"\n thyStopPropagation\n thyForm\n #linkForm=\"thyForm\"\n [thyFormValidatorConfig]=\"validatorConfig\"\n name=\"linkForm\"\n class=\"p-5\"\n>\n <thy-form-group thyLabelText=\"\u6587\u672C\">\n <input thyInput placeholder=\"\u8F93\u5165\u6587\u672C\" name=\"text\" [(ngModel)]=\"text\" thyAutofocus type=\"text\" />\n </thy-form-group>\n <thy-form-group thyLabelText=\"\u94FE\u63A5\">\n <input name=\"url\" thyInput placeholder=\"\u8F93\u5165\u94FE\u63A5\" [pattern]=\"URLRegex\" type=\"text\" [(ngModel)]=\"url\" />\n </thy-form-group>\n <thy-form-group-footer thyAlign=\"right\">\n <div class=\"btn-pair\">\n <button thyStopPropagation thyButton=\"link-secondary\" thySize=\"sm\" (click)=\"close()\">\u53D6\u6D88</button>\n <button thyStopPropagation thyButton=\"primary\" thySize=\"sm\" (thyFormSubmit)=\"apply(linkForm)\">\u5E94\u7528</button>\n </div>\n </thy-form-group-footer>\n</form>\n" }]
1157
+ ], template: "<form\n thyLayout=\"vertical\"\n thyStopPropagation\n thyForm\n #linkForm=\"thyForm\"\n [thyFormValidatorConfig]=\"validatorConfig()\"\n name=\"linkForm\"\n class=\"p-5\"\n>\n <thy-form-group [thyLabelText]=\"i18nTexts().linkText\">\n <input thyInput [placeholder]=\"i18nTexts().textPlaceholder\" />\n </thy-form-group>\n <thy-form-group [thyLabelText]=\"i18nTexts().urlLabel\">\n <input name=\"url\" thyInput [placeholder]=\"i18nTexts().urlPlaceholder\" [pattern]=\"URLRegex\" type=\"text\" [(ngModel)]=\"url\" />\n </thy-form-group>\n <thy-form-group-footer thyAlign=\"right\">\n <div class=\"btn-pair\">\n <button thyStopPropagation thyButton=\"link-secondary\" thySize=\"sm\" (click)=\"close()\">{{i18nTexts().cancel}}</button>\n <button thyStopPropagation thyButton=\"primary\" thySize=\"sm\" (thyFormSubmit)=\"apply(linkForm)\">{{i18nTexts().apply}}</button>\n </div>\n </thy-form-group-footer>\n</form>\n" }]
1040
1158
  }], ctorParameters: () => [{ type: i1$1.ThyPopoverRef }], propDecorators: { url: [{
1041
1159
  type: Input
1042
1160
  }], text: [{
@@ -1055,6 +1173,9 @@ class LinkCellEditorComponent extends AbstractEditCellEditor {
1055
1173
  this.cdr = inject(ChangeDetectorRef);
1056
1174
  this.notifyService = inject(ThyNotifyService);
1057
1175
  this.isOpened = false;
1176
+ this.linkTooltip = computed(() => {
1177
+ return getI18nTextByKey(this.aiTable, AITableGridI18nKey.linkTooltip);
1178
+ });
1058
1179
  }
1059
1180
  isValidLink(link) {
1060
1181
  if (!link?.text?.trim()) {
@@ -1089,7 +1210,7 @@ class LinkCellEditorComponent extends AbstractEditCellEditor {
1089
1210
  }
1090
1211
  updateValue() {
1091
1212
  if (!this.isValidLink({ text: this.text, url: this.url ?? '' })) {
1092
- this.notifyService.error('链接格式不正确');
1213
+ this.notifyService.error(getI18nTextByKey(this.aiTable, AITableGridI18nKey.invalidLinkFormat));
1093
1214
  return;
1094
1215
  }
1095
1216
  this.modelValue = this.createLinkValue({ text: this.text, url: this.url ?? '' });
@@ -1108,7 +1229,8 @@ class LinkCellEditorComponent extends AbstractEditCellEditor {
1108
1229
  width: this.elementRef.nativeElement.clientWidth + 'px',
1109
1230
  initialState: {
1110
1231
  url: this.url ?? '',
1111
- text: this.text ?? ''
1232
+ text: this.text ?? '',
1233
+ aiTable: this.aiTable
1112
1234
  }
1113
1235
  });
1114
1236
  if (popoverRef) {
@@ -1124,7 +1246,7 @@ class LinkCellEditorComponent extends AbstractEditCellEditor {
1124
1246
  }
1125
1247
  }
1126
1248
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LinkCellEditorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1127
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: LinkCellEditorComponent, isStandalone: true, selector: "link-cell-editor", host: { classAttribute: "ai-table-link-editor" }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<thy-input-group class=\"link-input-group h-100\" thySize=\"lg\">\n <input\n #inputElement\n class=\"h-100\"\n class=\"link-input\"\n thyInput\n thySize=\"md\"\n [thyAutofocus]=\"true\"\n [(ngModel)]=\"text\"\n (blur)=\"blur($event)\"\n (thyEnter)=\"updateValue()\"\n />\n <ng-template #suffix>\n <a\n thyAction\n thyIcon=\"link-insert\"\n thyTooltip=\"\u94FE\u63A5\"\n class=\"font-size-base edit-icon\"\n [class.active]=\"isOpened\"\n href=\"javascript:;\"\n (click)=\"openEdit()\"\n ></a>\n </ng-template>\n</thy-input-group>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ThyAutofocusDirective, selector: "input[thyAutofocus],textarea[thyAutofocus]", inputs: ["thyAutofocus", "thyAutoSelect"] }, { kind: "directive", type: ThyEnterDirective, selector: "[thyEnter]", outputs: ["thyEnter"] }, { kind: "component", type: ThyInputGroup, selector: "thy-input-group", inputs: ["thyAppendText", "thyAppendTextTranslateKey", "thyPrependText", "thyPrependTextTranslateKey", "thySize"] }, { kind: "ngmodule", type: ThyTooltipModule }, { kind: "directive", type: i2$1.ThyTooltipDirective, selector: "[thyTooltip],[thy-tooltip]", inputs: ["thyTooltip", "thyTooltipPlacement", "thyTooltipClass", "thyTooltipShowDelay", "thyTooltipHideDelay", "thyTooltipTrigger", "thyTooltipDisabled", "thyTooltipTemplateContext", "thyTooltipOffset", "thyTooltipPin"], exportAs: ["thyTooltip"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyInputModule }, { kind: "directive", type: i3.ThyInputDirective, selector: "input[thyInput], select[thyInput], textarea[thyInput]", inputs: ["thySize"], exportAs: ["thyInput"] }, { kind: "ngmodule", type: ThyFlexibleTextModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1249
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: LinkCellEditorComponent, isStandalone: true, selector: "link-cell-editor", host: { classAttribute: "ai-table-link-editor" }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<thy-input-group class=\"link-input-group h-100\" thySize=\"lg\">\n <input\n #inputElement\n class=\"h-100\"\n class=\"link-input\"\n thyInput\n thySize=\"md\"\n [thyAutofocus]=\"true\"\n [(ngModel)]=\"text\"\n (blur)=\"blur($event)\"\n (thyEnter)=\"updateValue()\"\n />\n <ng-template #suffix>\n <a\n thyAction\n thyIcon=\"link-insert\"\n [thyTooltip]=\"linkTooltip()\"\n class=\"font-size-base edit-icon\"\n [class.active]=\"isOpened\"\n href=\"javascript:;\"\n (click)=\"openEdit()\"\n ></a>\n </ng-template>\n</thy-input-group>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ThyAutofocusDirective, selector: "input[thyAutofocus],textarea[thyAutofocus]", inputs: ["thyAutofocus", "thyAutoSelect"] }, { kind: "directive", type: ThyEnterDirective, selector: "[thyEnter]", outputs: ["thyEnter"] }, { kind: "component", type: ThyInputGroup, selector: "thy-input-group", inputs: ["thyAppendText", "thyAppendTextTranslateKey", "thyPrependText", "thyPrependTextTranslateKey", "thySize"] }, { kind: "ngmodule", type: ThyTooltipModule }, { kind: "directive", type: i2$1.ThyTooltipDirective, selector: "[thyTooltip],[thy-tooltip]", inputs: ["thyTooltip", "thyTooltipPlacement", "thyTooltipClass", "thyTooltipShowDelay", "thyTooltipHideDelay", "thyTooltipTrigger", "thyTooltipDisabled", "thyTooltipTemplateContext", "thyTooltipOffset", "thyTooltipPin"], exportAs: ["thyTooltip"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyInputModule }, { kind: "directive", type: i3.ThyInputDirective, selector: "input[thyInput], select[thyInput], textarea[thyInput]", inputs: ["thySize"], exportAs: ["thyInput"] }, { kind: "ngmodule", type: ThyFlexibleTextModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1128
1250
  }
1129
1251
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LinkCellEditorComponent, decorators: [{
1130
1252
  type: Component,
@@ -1136,11 +1258,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1136
1258
  ThyTooltipModule,
1137
1259
  ThyAction,
1138
1260
  ThyInputModule,
1139
- ThyFlexibleTextModule,
1140
- LinkEditComponent
1261
+ ThyFlexibleTextModule
1141
1262
  ], host: {
1142
1263
  class: 'ai-table-link-editor'
1143
- }, template: "<thy-input-group class=\"link-input-group h-100\" thySize=\"lg\">\n <input\n #inputElement\n class=\"h-100\"\n class=\"link-input\"\n thyInput\n thySize=\"md\"\n [thyAutofocus]=\"true\"\n [(ngModel)]=\"text\"\n (blur)=\"blur($event)\"\n (thyEnter)=\"updateValue()\"\n />\n <ng-template #suffix>\n <a\n thyAction\n thyIcon=\"link-insert\"\n thyTooltip=\"\u94FE\u63A5\"\n class=\"font-size-base edit-icon\"\n [class.active]=\"isOpened\"\n href=\"javascript:;\"\n (click)=\"openEdit()\"\n ></a>\n </ng-template>\n</thy-input-group>\n" }]
1264
+ }, template: "<thy-input-group class=\"link-input-group h-100\" thySize=\"lg\">\n <input\n #inputElement\n class=\"h-100\"\n class=\"link-input\"\n thyInput\n thySize=\"md\"\n [thyAutofocus]=\"true\"\n [(ngModel)]=\"text\"\n (blur)=\"blur($event)\"\n (thyEnter)=\"updateValue()\"\n />\n <ng-template #suffix>\n <a\n thyAction\n thyIcon=\"link-insert\"\n [thyTooltip]=\"linkTooltip()\"\n class=\"font-size-base edit-icon\"\n [class.active]=\"isOpened\"\n href=\"javascript:;\"\n (click)=\"openEdit()\"\n ></a>\n </ng-template>\n</thy-input-group>\n" }]
1144
1265
  }], propDecorators: { inputElement: [{
1145
1266
  type: ViewChild,
1146
1267
  args: ['inputElement', { static: false }]
@@ -1529,18 +1650,22 @@ class AITableFieldSetting {
1529
1650
  this.addField = output();
1530
1651
  this.setField = output();
1531
1652
  this.selectedFieldOption = computed(() => {
1532
- return getFieldOptionByField(this.aiEditField());
1653
+ return getFieldOptionByField(this.aiTable(), this.aiEditField());
1533
1654
  });
1534
1655
  this.fieldMaxLength = 32;
1535
- this.validatorConfig = {
1536
- validationMessages: {
1537
- fieldName: {
1538
- required: '列名不能为空',
1539
- thyUniqueCheck: '列名已存在'
1656
+ this.validatorConfig = computed(() => {
1657
+ return {
1658
+ validationMessages: {
1659
+ fieldName: {
1660
+ required: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldNameRequired),
1661
+ thyUniqueCheck: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldNameDuplicate)
1662
+ }
1540
1663
  }
1541
- }
1542
- };
1543
- this.fieldOptions = _.cloneDeep(FieldOptions);
1664
+ };
1665
+ });
1666
+ this.fieldOptions = computed(() => {
1667
+ return getFieldOptions(this.aiTable());
1668
+ });
1544
1669
  this.aITableFieldType = AITableFieldType;
1545
1670
  this.isMultipleMember = false;
1546
1671
  this.thyPopoverRef = inject((ThyPopoverRef));
@@ -1550,6 +1675,16 @@ class AITableFieldSetting {
1550
1675
  .fields()
1551
1676
  ?.find((field) => field.name === fieldName && this.aiEditField()?._id !== field._id));
1552
1677
  };
1678
+ this.i18nTexts = computed(() => {
1679
+ return {
1680
+ columnName: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldColumnName),
1681
+ columnNamePlaceholder: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldColumnNamePlaceholder),
1682
+ fieldType: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldType),
1683
+ allowMultipleMembers: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.allowMultipleMembers),
1684
+ cancel: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.cancel),
1685
+ confirm: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.confirm)
1686
+ };
1687
+ });
1553
1688
  }
1554
1689
  ngOnInit() {
1555
1690
  this.isMultipleMember =
@@ -1595,7 +1730,7 @@ class AITableFieldSetting {
1595
1730
  this.thyPopoverRef.close();
1596
1731
  }
1597
1732
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableFieldSetting, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1598
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableFieldSetting, isStandalone: true, selector: "ai-table-field-setting", inputs: { aiEditField: { classPropertyName: "aiEditField", publicName: "aiEditField", isSignal: true, isRequired: true, transformFunction: null }, aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: true, transformFunction: null }, aiExternalTemplate: { classPropertyName: "aiExternalTemplate", publicName: "aiExternalTemplate", isSignal: true, isRequired: false, transformFunction: null }, isUpdate: { classPropertyName: "isUpdate", publicName: "isUpdate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiEditField: "aiEditFieldChange", addField: "addField", setField: "setField" }, host: { classAttribute: "field-setting d-block pl-5 pr-5 pb-5 pt-4" }, ngImport: i0, template: "<form thyForm name=\"createPropertyForm\" [thyFormValidatorConfig]=\"validatorConfig\" thyLayout=\"vertical\">\n <thy-form-group thyLabelRequired thyLabelText=\"\u8868\u683C\u5217\u540D\">\n <thy-input-group>\n <input\n thyInput\n [thyAutofocus]=\"true\"\n name=\"fieldName\"\n [maxlength]=\"fieldMaxLength\"\n [(ngModel)]=\"aiEditField().name\"\n required\n placeholder=\"\u8F93\u5165\u5217\u540D\u79F0\"\n [thyUniqueCheck]=\"checkUniqueName\"\n />\n <ng-template #suffix>\n <thy-input-count></thy-input-count>\n </ng-template>\n </thy-input-group>\n </thy-form-group>\n <thy-form-group thyLabelText=\"\u5217\u7C7B\u578B\">\n <div class=\"thy-dropdown-menu py-0\">\n <div class=\"ml-n5 mr-n5\">\n <span\n thyDropdownMenuItem\n [thyDropdown]=\"menu\"\n [thyDisabled]=\"isUpdate()\"\n thyTrigger=\"hover\"\n thyPlacement=\"right\"\n (click)=\"fieldTypeClick($event)\"\n >\n <thy-icon thyDropdownMenuItemIcon [thyIconName]=\"selectedFieldOption().icon\"></thy-icon>\n <span thyDropdownMenuItemName>{{ selectedFieldOption().name }}</span>\n <thy-icon thyDropdownMenuItemExtendIcon thyIconName=\"angle-right\" class=\"text-desc\"></thy-icon>\n </span>\n </div>\n </div>\n\n @if (selectedFieldOption().type === aITableFieldType.member) {\n <div class=\"d-flex justify-content-between mt-3\">\n \u5141\u8BB8\u9009\u62E9\u591A\u4E2A\u6210\u5458\n <thy-switch\n name=\"isMultipleMember\"\n [thyDisabled]=\"isUpdate()\"\n [(ngModel)]=\"isMultipleMember\"\n (ngModelChange)=\"multipleMemberChange()\"\n thySize=\"sm\"\n ></thy-switch>\n </div>\n }\n </thy-form-group>\n @if (aiExternalTemplate()) {\n <ng-container *ngTemplateOutlet=\"aiExternalTemplate()\"></ng-container>\n }\n <thy-form-group-footer thyAlign=\"right\">\n <button thyButton=\"link-secondary\" (click)=\"cancel()\" thySize=\"sm\">\u53D6\u6D88</button>\n <button thyButton=\"primary\" (thyFormSubmit)=\"editFieldProperty()\" thySize=\"sm\">\u786E\u5B9A</button>\n </thy-form-group-footer>\n</form>\n\n<thy-dropdown-menu #menu>\n @for (item of fieldOptions; track $index) {\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{\n active: (item | fieldIsSameOption: aiEditField())\n }\"\n (click)=\"selectFieldType(item)\"\n >\n <thy-icon [thyIconName]=\"item.icon!\"></thy-icon>\n <span thyDropdownMenuItemName>{{ item.name }}</span>\n </a>\n }\n</thy-dropdown-menu>\n", styles: [":host{width:350px}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyInputGroup, selector: "thy-input-group", inputs: ["thyAppendText", "thyAppendTextTranslateKey", "thyPrependText", "thyPrependTextTranslateKey", "thySize"] }, { kind: "component", type: ThyInputCount, selector: "thy-input-count", inputs: ["thyInput"] }, { kind: "directive", type: ThyInputDirective, selector: "input[thyInput], select[thyInput], textarea[thyInput]", inputs: ["thySize"], exportAs: ["thyInput"] }, { kind: "directive", type: ThyUniqueCheckValidator, selector: "[thyUniqueCheck]", inputs: ["thyUniqueCheck"] }, { kind: "component", type: ThyDropdownMenuComponent, selector: "thy-dropdown-menu", inputs: ["thyWidth", "thyImmediateRender"] }, { kind: "directive", type: ThyDropdownDirective, selector: "[thyDropdown]", inputs: ["thyDropdownMenu", "thyDropdown", "thyTrigger", "thyShowDelay", "thyHideDelay", "thyActiveClass", "thyPopoverOptions", "thyPlacement", "thyMenuInsideClosable", "thyPanelClass"], outputs: ["thyActiveChange"] }, { kind: "directive", type: ThyDropdownMenuItemDirective, selector: "[thyDropdownMenuItem]", inputs: ["thyType", "thyDisabled"] }, { kind: "directive", type: ThyDropdownMenuItemIconDirective, selector: "[thyDropdownMenuItemIcon]" }, { kind: "directive", type: ThyDropdownMenuItemNameDirective, selector: "[thyDropdownMenuItemName]" }, { kind: "directive", type: ThyDropdownMenuItemExtendIconDirective, selector: "[thyDropdownMenuItemExtendIcon]" }, { kind: "component", type: ThyButton, selector: "thy-button,[thy-button],[thyButton]", inputs: ["thyButton", "thyType", "thyLoading", "thyLoadingText", "thySize", "thyIcon", "thyBlock"] }, { kind: "component", type: ThySwitch, selector: "thy-switch", inputs: ["thyType", "thySize", "thyDisabled", "thyLoading"], outputs: ["thyChange"] }, { kind: "ngmodule", type: ThyFormModule }, { kind: "directive", type: i2.ThyFormDirective, selector: "[thyForm],[thy-form]", inputs: ["thyLayout", "thyEnterKeyMode", "thyFormValidatorConfig"], exportAs: ["thyForm"] }, { kind: "component", type: i2.ThyFormGroup, selector: "thy-form-group", inputs: ["thyLabelText", "thyLabelTextTranslateKey", "thyLabelRequired", "thyLabelPaddingTopClear", "thyFeedbackIcon", "thyTipsMode", "thyTips", "thyTipsTranslateKey", "thyRowFill"] }, { kind: "directive", type: i2.ThyFormSubmitDirective, selector: "[thyFormSubmit],[thy-form-submit]", outputs: ["thyFormSubmit"] }, { kind: "component", type: i2.ThyFormGroupFooter, selector: "thy-form-group-footer", inputs: ["thyAlign"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ThyAutofocusDirective, selector: "input[thyAutofocus],textarea[thyAutofocus]", inputs: ["thyAutofocus", "thyAutoSelect"] }, { kind: "pipe", type: AITableFieldIsSameOptionPipe, name: "fieldIsSameOption" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1733
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableFieldSetting, isStandalone: true, selector: "ai-table-field-setting", inputs: { aiEditField: { classPropertyName: "aiEditField", publicName: "aiEditField", isSignal: true, isRequired: true, transformFunction: null }, aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: true, transformFunction: null }, aiExternalTemplate: { classPropertyName: "aiExternalTemplate", publicName: "aiExternalTemplate", isSignal: true, isRequired: false, transformFunction: null }, isUpdate: { classPropertyName: "isUpdate", publicName: "isUpdate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiEditField: "aiEditFieldChange", addField: "addField", setField: "setField" }, host: { classAttribute: "field-setting d-block pl-5 pr-5 pb-5 pt-4" }, ngImport: i0, template: "<form thyForm name=\"createPropertyForm\" [thyFormValidatorConfig]=\"validatorConfig()\" thyLayout=\"vertical\">\n <thy-form-group thyLabelRequired [thyLabelText]=\"i18nTexts().columnName\">\n <thy-input-group>\n <input\n thyInput\n [thyAutofocus]=\"true\"\n name=\"fieldName\"\n [maxlength]=\"fieldMaxLength\"\n [(ngModel)]=\"aiEditField().name\"\n required\n [placeholder]=\"i18nTexts().columnNamePlaceholder\"\n [thyUniqueCheck]=\"checkUniqueName\"\n />\n <ng-template #suffix>\n <thy-input-count></thy-input-count>\n </ng-template>\n </thy-input-group>\n </thy-form-group>\n <thy-form-group [thyLabelText]=\"i18nTexts().fieldType\">\n <div class=\"thy-dropdown-menu py-0\">\n <div class=\"ml-n5 mr-n5\">\n <span\n thyDropdownMenuItem\n [thyDropdown]=\"menu\"\n [thyDisabled]=\"isUpdate()\"\n thyTrigger=\"hover\"\n thyPlacement=\"right\"\n (click)=\"fieldTypeClick($event)\"\n >\n <thy-icon thyDropdownMenuItemIcon [thyIconName]=\"selectedFieldOption().icon\"></thy-icon>\n <span thyDropdownMenuItemName>{{ selectedFieldOption().name }}</span>\n <thy-icon thyDropdownMenuItemExtendIcon thyIconName=\"angle-right\" class=\"text-desc\"></thy-icon>\n </span>\n </div>\n </div>\n\n @if (selectedFieldOption().type === aITableFieldType.member) {\n <div class=\"d-flex justify-content-between mt-3\">\n {{i18nTexts().allowMultipleMembers}}\n <thy-switch\n name=\"isMultipleMember\"\n [thyDisabled]=\"isUpdate()\"\n [(ngModel)]=\"isMultipleMember\"\n (ngModelChange)=\"multipleMemberChange()\"\n thySize=\"sm\"\n ></thy-switch>\n </div>\n }\n </thy-form-group>\n @if (aiExternalTemplate()) {\n <ng-container *ngTemplateOutlet=\"aiExternalTemplate()\"></ng-container>\n }\n <thy-form-group-footer thyAlign=\"right\">\n <button thyButton=\"link-secondary\" (click)=\"cancel()\" thySize=\"sm\">{{i18nTexts().cancel}}</button>\n <button thyButton=\"primary\" (thyFormSubmit)=\"editFieldProperty()\" thySize=\"sm\">{{i18nTexts().confirm}}</button>\n </thy-form-group-footer>\n</form>\n\n<thy-dropdown-menu #menu>\n @for (item of fieldOptions(); track $index) {\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{\n active: (item | fieldIsSameOption: aiEditField())\n }\"\n (click)=\"selectFieldType(item)\"\n >\n <thy-icon [thyIconName]=\"item.icon!\"></thy-icon>\n <span thyDropdownMenuItemName>{{ item.name }}</span>\n </a>\n }\n</thy-dropdown-menu>\n", styles: [":host{width:350px}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyInputGroup, selector: "thy-input-group", inputs: ["thyAppendText", "thyAppendTextTranslateKey", "thyPrependText", "thyPrependTextTranslateKey", "thySize"] }, { kind: "component", type: ThyInputCount, selector: "thy-input-count", inputs: ["thyInput"] }, { kind: "directive", type: ThyInputDirective, selector: "input[thyInput], select[thyInput], textarea[thyInput]", inputs: ["thySize"], exportAs: ["thyInput"] }, { kind: "directive", type: ThyUniqueCheckValidator, selector: "[thyUniqueCheck]", inputs: ["thyUniqueCheck"] }, { kind: "component", type: ThyDropdownMenuComponent, selector: "thy-dropdown-menu", inputs: ["thyWidth", "thyImmediateRender"] }, { kind: "directive", type: ThyDropdownDirective, selector: "[thyDropdown]", inputs: ["thyDropdownMenu", "thyDropdown", "thyTrigger", "thyShowDelay", "thyHideDelay", "thyActiveClass", "thyPopoverOptions", "thyPlacement", "thyMenuInsideClosable", "thyPanelClass"], outputs: ["thyActiveChange"] }, { kind: "directive", type: ThyDropdownMenuItemDirective, selector: "[thyDropdownMenuItem]", inputs: ["thyType", "thyDisabled"] }, { kind: "directive", type: ThyDropdownMenuItemIconDirective, selector: "[thyDropdownMenuItemIcon]" }, { kind: "directive", type: ThyDropdownMenuItemNameDirective, selector: "[thyDropdownMenuItemName]" }, { kind: "directive", type: ThyDropdownMenuItemExtendIconDirective, selector: "[thyDropdownMenuItemExtendIcon]" }, { kind: "component", type: ThyButton, selector: "thy-button,[thy-button],[thyButton]", inputs: ["thyButton", "thyType", "thyLoading", "thyLoadingText", "thySize", "thyIcon", "thyBlock"] }, { kind: "component", type: ThySwitch, selector: "thy-switch", inputs: ["thyType", "thySize", "thyDisabled", "thyLoading"], outputs: ["thyChange"] }, { kind: "ngmodule", type: ThyFormModule }, { kind: "directive", type: i2.ThyFormDirective, selector: "[thyForm],[thy-form]", inputs: ["thyLayout", "thyEnterKeyMode", "thyFormValidatorConfig"], exportAs: ["thyForm"] }, { kind: "component", type: i2.ThyFormGroup, selector: "thy-form-group", inputs: ["thyLabelText", "thyLabelTextTranslateKey", "thyLabelRequired", "thyLabelPaddingTopClear", "thyFeedbackIcon", "thyTipsMode", "thyTips", "thyTipsTranslateKey", "thyRowFill"] }, { kind: "directive", type: i2.ThyFormSubmitDirective, selector: "[thyFormSubmit],[thy-form-submit]", outputs: ["thyFormSubmit"] }, { kind: "component", type: i2.ThyFormGroupFooter, selector: "thy-form-group-footer", inputs: ["thyAlign"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ThyAutofocusDirective, selector: "input[thyAutofocus],textarea[thyAutofocus]", inputs: ["thyAutofocus", "thyAutoSelect"] }, { kind: "pipe", type: AITableFieldIsSameOptionPipe, name: "fieldIsSameOption" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1599
1734
  }
1600
1735
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableFieldSetting, decorators: [{
1601
1736
  type: Component,
@@ -1621,7 +1756,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1621
1756
  AITableFieldIsSameOptionPipe
1622
1757
  ], host: {
1623
1758
  class: 'field-setting d-block pl-5 pr-5 pb-5 pt-4'
1624
- }, template: "<form thyForm name=\"createPropertyForm\" [thyFormValidatorConfig]=\"validatorConfig\" thyLayout=\"vertical\">\n <thy-form-group thyLabelRequired thyLabelText=\"\u8868\u683C\u5217\u540D\">\n <thy-input-group>\n <input\n thyInput\n [thyAutofocus]=\"true\"\n name=\"fieldName\"\n [maxlength]=\"fieldMaxLength\"\n [(ngModel)]=\"aiEditField().name\"\n required\n placeholder=\"\u8F93\u5165\u5217\u540D\u79F0\"\n [thyUniqueCheck]=\"checkUniqueName\"\n />\n <ng-template #suffix>\n <thy-input-count></thy-input-count>\n </ng-template>\n </thy-input-group>\n </thy-form-group>\n <thy-form-group thyLabelText=\"\u5217\u7C7B\u578B\">\n <div class=\"thy-dropdown-menu py-0\">\n <div class=\"ml-n5 mr-n5\">\n <span\n thyDropdownMenuItem\n [thyDropdown]=\"menu\"\n [thyDisabled]=\"isUpdate()\"\n thyTrigger=\"hover\"\n thyPlacement=\"right\"\n (click)=\"fieldTypeClick($event)\"\n >\n <thy-icon thyDropdownMenuItemIcon [thyIconName]=\"selectedFieldOption().icon\"></thy-icon>\n <span thyDropdownMenuItemName>{{ selectedFieldOption().name }}</span>\n <thy-icon thyDropdownMenuItemExtendIcon thyIconName=\"angle-right\" class=\"text-desc\"></thy-icon>\n </span>\n </div>\n </div>\n\n @if (selectedFieldOption().type === aITableFieldType.member) {\n <div class=\"d-flex justify-content-between mt-3\">\n \u5141\u8BB8\u9009\u62E9\u591A\u4E2A\u6210\u5458\n <thy-switch\n name=\"isMultipleMember\"\n [thyDisabled]=\"isUpdate()\"\n [(ngModel)]=\"isMultipleMember\"\n (ngModelChange)=\"multipleMemberChange()\"\n thySize=\"sm\"\n ></thy-switch>\n </div>\n }\n </thy-form-group>\n @if (aiExternalTemplate()) {\n <ng-container *ngTemplateOutlet=\"aiExternalTemplate()\"></ng-container>\n }\n <thy-form-group-footer thyAlign=\"right\">\n <button thyButton=\"link-secondary\" (click)=\"cancel()\" thySize=\"sm\">\u53D6\u6D88</button>\n <button thyButton=\"primary\" (thyFormSubmit)=\"editFieldProperty()\" thySize=\"sm\">\u786E\u5B9A</button>\n </thy-form-group-footer>\n</form>\n\n<thy-dropdown-menu #menu>\n @for (item of fieldOptions; track $index) {\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{\n active: (item | fieldIsSameOption: aiEditField())\n }\"\n (click)=\"selectFieldType(item)\"\n >\n <thy-icon [thyIconName]=\"item.icon!\"></thy-icon>\n <span thyDropdownMenuItemName>{{ item.name }}</span>\n </a>\n }\n</thy-dropdown-menu>\n", styles: [":host{width:350px}\n"] }]
1759
+ }, template: "<form thyForm name=\"createPropertyForm\" [thyFormValidatorConfig]=\"validatorConfig()\" thyLayout=\"vertical\">\n <thy-form-group thyLabelRequired [thyLabelText]=\"i18nTexts().columnName\">\n <thy-input-group>\n <input\n thyInput\n [thyAutofocus]=\"true\"\n name=\"fieldName\"\n [maxlength]=\"fieldMaxLength\"\n [(ngModel)]=\"aiEditField().name\"\n required\n [placeholder]=\"i18nTexts().columnNamePlaceholder\"\n [thyUniqueCheck]=\"checkUniqueName\"\n />\n <ng-template #suffix>\n <thy-input-count></thy-input-count>\n </ng-template>\n </thy-input-group>\n </thy-form-group>\n <thy-form-group [thyLabelText]=\"i18nTexts().fieldType\">\n <div class=\"thy-dropdown-menu py-0\">\n <div class=\"ml-n5 mr-n5\">\n <span\n thyDropdownMenuItem\n [thyDropdown]=\"menu\"\n [thyDisabled]=\"isUpdate()\"\n thyTrigger=\"hover\"\n thyPlacement=\"right\"\n (click)=\"fieldTypeClick($event)\"\n >\n <thy-icon thyDropdownMenuItemIcon [thyIconName]=\"selectedFieldOption().icon\"></thy-icon>\n <span thyDropdownMenuItemName>{{ selectedFieldOption().name }}</span>\n <thy-icon thyDropdownMenuItemExtendIcon thyIconName=\"angle-right\" class=\"text-desc\"></thy-icon>\n </span>\n </div>\n </div>\n\n @if (selectedFieldOption().type === aITableFieldType.member) {\n <div class=\"d-flex justify-content-between mt-3\">\n {{i18nTexts().allowMultipleMembers}}\n <thy-switch\n name=\"isMultipleMember\"\n [thyDisabled]=\"isUpdate()\"\n [(ngModel)]=\"isMultipleMember\"\n (ngModelChange)=\"multipleMemberChange()\"\n thySize=\"sm\"\n ></thy-switch>\n </div>\n }\n </thy-form-group>\n @if (aiExternalTemplate()) {\n <ng-container *ngTemplateOutlet=\"aiExternalTemplate()\"></ng-container>\n }\n <thy-form-group-footer thyAlign=\"right\">\n <button thyButton=\"link-secondary\" (click)=\"cancel()\" thySize=\"sm\">{{i18nTexts().cancel}}</button>\n <button thyButton=\"primary\" (thyFormSubmit)=\"editFieldProperty()\" thySize=\"sm\">{{i18nTexts().confirm}}</button>\n </thy-form-group-footer>\n</form>\n\n<thy-dropdown-menu #menu>\n @for (item of fieldOptions(); track $index) {\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{\n active: (item | fieldIsSameOption: aiEditField())\n }\"\n (click)=\"selectFieldType(item)\"\n >\n <thy-icon [thyIconName]=\"item.icon!\"></thy-icon>\n <span thyDropdownMenuItemName>{{ item.name }}</span>\n </a>\n }\n</thy-dropdown-menu>\n", styles: [":host{width:350px}\n"] }]
1625
1760
  }] });
1626
1761
 
1627
1762
  class AITableGridSelectionService {
@@ -1813,6 +1948,8 @@ const GRID_CELL_EDITOR_MAP = {
1813
1948
  };
1814
1949
 
1815
1950
  const AI_TABLE_ACTION_COMMON_SIZE = 32; // 表格图标action背景的通用尺寸
1951
+ const AI_TABLE_ACTION_COMMON_RADIUS = 4; // 表格图标action背景的radius通用尺寸
1952
+ const AI_TABLE_ACTION_COMMON_RIGHT_PADDING = 6; // 表格图标action右侧padding尺寸
1816
1953
  const AI_TABLE_DEFAULT_COLUMN_WIDTH = 200; // 默认列宽
1817
1954
  const AI_TABLE_SCROLL_BAR_PADDING = 3; // 单元格滑动容器的滚动条宽度
1818
1955
  const AI_TABLE_OFFSET = 0.5; // 边框线偏移值
@@ -1827,6 +1964,8 @@ const AI_TABLE_FIELD_HEAD_HEIGHT = 44; // 表格字段列头的高度
1827
1964
  const AI_TABLE_ROW_BLANK_HEIGHT = 43; // 减去边框后真实的行高
1828
1965
  const AI_TABLE_ROW_HEIGHT = 44; // 默认行高基准
1829
1966
  const AI_TABLE_CELL_ACTIVE_BORDER_WIDTH = 2; // 选中单元格的边框宽度
1967
+ const AI_TABLE_CELL_ATTACHMENT_ADD = 'AI_TABLE_CELL_ATTACHMENT_ADD'; // 附件cell中新增图标名称
1968
+ const AI_TABLE_CELL_ATTACHMENT_FILE = 'AI_TABLE_CELL_ATTACHMENT_FILE'; // 附件cell中文件
1830
1969
  const AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH = 30; // 字段列头文本的最小宽度
1831
1970
  const AI_TABLE_ROW_SELECT_CHECKBOX = 'AI_TABLE_ROW_SELECT_CHECKBOX'; // 行 checkbox
1832
1971
  const AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX = 'AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX'; // 表头 checkbox 标识
@@ -1863,7 +2002,7 @@ const AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT = 8; // 成员头像与成员名
1863
2002
  const AI_TABLE_FILE_ICON_ITEM_HEIGHT = 20; // 文件字段项高度
1864
2003
  const AI_TABLE_FILE_ICON_SIZE = 20; // 文件图标大小
1865
2004
  const AI_TABLE_CELL_FIELD_ITEM_HEIGHT = 8; // 文件字段项右边距
1866
- const AI_TABLE_FIELD_ITEM_MARGIN_RIGHT = 4; // 文件图标之间的间距
2005
+ const AI_TABLE_FIELD_ITEM_MARGIN_RIGHT = 8; // 文件图标之间的间距
1867
2006
  const AI_TABLE_OPTION_ITEM_PADDING = 10; // 选项按钮间距
1868
2007
  const AI_TABLE_OPTION_ITEM_HEIGHT = 24;
1869
2008
  const AI_TABLE_OPTION_ITEM_FONT_SIZE = 14;
@@ -1886,7 +2025,6 @@ const DBL_CLICK_EDIT_TYPE = [
1886
2025
  AITableFieldType.select,
1887
2026
  AITableFieldType.date,
1888
2027
  AITableFieldType.member,
1889
- AITableFieldType.attachment,
1890
2028
  AITableFieldType.link
1891
2029
  ];
1892
2030
  const MOUSEOVER_EDIT_TYPE = [AITableFieldType.progress, AITableFieldType.rate];
@@ -1974,14 +2112,20 @@ class AITableFieldMenu extends ThyDropdownAbstractMenu {
1974
2112
  menu.exec && menu.exec(this.aiTable, this.field, this.origin, this.position);
1975
2113
  }
1976
2114
  }
2115
+ getMenuName(menu, field) {
2116
+ if (typeof menu.name === 'function') {
2117
+ return menu.name(field);
2118
+ }
2119
+ return menu.name || '';
2120
+ }
1977
2121
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableFieldMenu, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1978
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableFieldMenu, isStandalone: true, selector: "ai-table-field-menu", inputs: { fieldId: "fieldId", aiTable: "aiTable", fieldMenus: "fieldMenus", origin: "origin", position: "position" }, host: { classAttribute: "field-menu" }, usesInheritance: true, ngImport: i0, template: "@for (menu of fieldMenus; track index; let index = $index) {\n @if ((menu.hidden && !menu.hidden(aiTable, field)) || !menu.hidden) {\n @if (menu.type === 'divider') {\n <thy-divider [thyStyle]=\"'solid'\"></thy-divider>\n } @else {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable, field));\n @let isRemoveField = menu.type === 'removeField';\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'remove-field': isRemoveField && !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ menu.name! }}</span>\n </a>\n }\n }\n}\n", dependencies: [{ kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyDivider, selector: "thy-divider", inputs: ["thyVertical", "thyStyle", "thyColor", "thyText", "thyTextDirection", "thyDeeper"] }, { kind: "directive", type: ThyDropdownMenuItemDirective, selector: "[thyDropdownMenuItem]", inputs: ["thyType", "thyDisabled"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2122
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableFieldMenu, isStandalone: true, selector: "ai-table-field-menu", inputs: { fieldId: "fieldId", aiTable: "aiTable", fieldMenus: "fieldMenus", origin: "origin", position: "position" }, host: { classAttribute: "field-menu" }, usesInheritance: true, ngImport: i0, template: "@for (menu of fieldMenus; track index; let index = $index) {\n @if ((menu.hidden && !menu.hidden(aiTable, field)) || !menu.hidden) {\n @if (menu.type === 'divider') {\n <thy-divider [thyStyle]=\"'solid'\"></thy-divider>\n } @else {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable, field));\n @let isRemoveField = menu.type === 'removeField';\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'remove-field': isRemoveField && !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ getMenuName(menu, field()) }}</span>\n </a>\n }\n }\n}\n", dependencies: [{ kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyDivider, selector: "thy-divider", inputs: ["thyVertical", "thyStyle", "thyColor", "thyText", "thyTextDirection", "thyDeeper"] }, { kind: "directive", type: ThyDropdownMenuItemDirective, selector: "[thyDropdownMenuItem]", inputs: ["thyType", "thyDisabled"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1979
2123
  }
1980
2124
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableFieldMenu, decorators: [{
1981
2125
  type: Component,
1982
2126
  args: [{ selector: 'ai-table-field-menu', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
1983
2127
  class: 'field-menu'
1984
- }, imports: [ThyIcon, ThyDivider, ThyDropdownMenuItemDirective, NgClass], template: "@for (menu of fieldMenus; track index; let index = $index) {\n @if ((menu.hidden && !menu.hidden(aiTable, field)) || !menu.hidden) {\n @if (menu.type === 'divider') {\n <thy-divider [thyStyle]=\"'solid'\"></thy-divider>\n } @else {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable, field));\n @let isRemoveField = menu.type === 'removeField';\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'remove-field': isRemoveField && !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ menu.name! }}</span>\n </a>\n }\n }\n}\n" }]
2128
+ }, imports: [ThyIcon, ThyDivider, ThyDropdownMenuItemDirective, NgClass], template: "@for (menu of fieldMenus; track index; let index = $index) {\n @if ((menu.hidden && !menu.hidden(aiTable, field)) || !menu.hidden) {\n @if (menu.type === 'divider') {\n <thy-divider [thyStyle]=\"'solid'\"></thy-divider>\n } @else {\n @let disabled = !!(menu.disabled && menu.disabled(aiTable, field));\n @let isRemoveField = menu.type === 'removeField';\n <a\n thyDropdownMenuItem\n href=\"javascript:;\"\n [ngClass]=\"{ 'remove-field': isRemoveField && !disabled }\"\n (click)=\"execute(menu)\"\n [thyDisabled]=\"disabled\"\n >\n <thy-icon [thyIconName]=\"menu.icon!\"></thy-icon>\n <span>{{ getMenuName(menu, field()) }}</span>\n </a>\n }\n }\n}\n" }]
1985
2129
  }], propDecorators: { fieldId: [{
1986
2130
  type: Input,
1987
2131
  args: [{ required: true }]
@@ -2018,9 +2162,10 @@ const buildGridLinearRows = (visibleRecords, isAddingVisible = true) => {
2018
2162
  });
2019
2163
  return linearRows;
2020
2164
  };
2021
- const buildGridData = (recordValue, fieldsValue) => {
2165
+ const buildGridData = (aiTable, recordValue, fieldsValue) => {
2166
+ const fieldOptions = getFieldOptions(aiTable);
2022
2167
  const fields = fieldsValue.map((value) => {
2023
- const fieldOption = FieldOptions.find((item) => item.type === value.type);
2168
+ const fieldOption = fieldOptions.find((item) => item.type === value.type);
2024
2169
  return {
2025
2170
  ...value,
2026
2171
  icon: value.icon || fieldOption.icon,
@@ -2085,10 +2230,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2085
2230
  type: Injectable
2086
2231
  }], ctorParameters: () => [{ type: i1$1.ThyPopover }] });
2087
2232
 
2088
- function getColumnIndicesSizeMap(fields) {
2233
+ function getColumnIndicesSizeMap(aiTable, fields) {
2089
2234
  const columnIndicesSizeMap = {};
2090
2235
  fields?.forEach((field, index) => {
2091
- columnIndicesSizeMap[index] = field.width ?? getFieldOptionByField(field).width;
2236
+ columnIndicesSizeMap[index] = field.width ?? getFieldOptionByField(aiTable, field).width;
2092
2237
  });
2093
2238
  return columnIndicesSizeMap;
2094
2239
  }
@@ -2157,9 +2302,9 @@ function getAvatarBgColor(name) {
2157
2302
  /**
2158
2303
  * 生成目标名称
2159
2304
  */
2160
- const generateTargetName = ({ targetName, fieldId, recordId, mouseStyle }) => {
2305
+ const generateTargetName = ({ targetName, fieldId, recordId, mouseStyle, source }) => {
2161
2306
  const flag = '$';
2162
- return `${targetName}.${fieldId || flag}.${recordId || flag}.${mouseStyle || flag}`;
2307
+ return `${targetName}.${fieldId || flag}.${recordId || flag}.${mouseStyle || flag}.${source || flag}`;
2163
2308
  };
2164
2309
  /**
2165
2310
  * 取目标名称
@@ -2182,12 +2327,13 @@ const getDetailByTargetName = (_targetName) => {
2182
2327
  };
2183
2328
  }
2184
2329
  const flag = '$';
2185
- const [targetName, fieldId, recordId, mouseStyle] = _targetName.split('.');
2330
+ const [targetName, fieldId, recordId, mouseStyle, source] = _targetName.split('.');
2186
2331
  return {
2187
2332
  targetName,
2188
2333
  fieldId: fieldId === flag ? null : fieldId,
2189
2334
  recordId: recordId === flag ? null : recordId,
2190
- mouseStyle: mouseStyle === flag ? null : mouseStyle
2335
+ mouseStyle: mouseStyle === flag ? null : mouseStyle,
2336
+ source: source === flag ? null : source
2191
2337
  };
2192
2338
  };
2193
2339
  /**
@@ -2688,21 +2834,15 @@ function toDateFieldValue(plainText, targetField, originData) {
2688
2834
  switch (field.type) {
2689
2835
  case AITableFieldType.date:
2690
2836
  return cellValue;
2691
- case AITableFieldType.text:
2692
- const dateValue = transformDateValue(cellValue);
2693
- if (dateValue) {
2694
- return dateValue;
2695
- }
2696
- break;
2697
2837
  default:
2698
2838
  break;
2699
2839
  }
2700
2840
  }
2701
- else {
2702
- const dateValue = transformDateValue(plainText);
2703
- if (dateValue) {
2704
- return dateValue;
2705
- }
2841
+ const texts = plainText.split(',');
2842
+ const value = texts && texts.length ? texts[0].trim() : plainText.trim();
2843
+ const dateValue = transformDateValue(value);
2844
+ if (dateValue) {
2845
+ return dateValue;
2706
2846
  }
2707
2847
  return null;
2708
2848
  }
@@ -3005,10 +3145,17 @@ function toProgressFieldValue(plainText, targetField, originData) {
3005
3145
  break;
3006
3146
  }
3007
3147
  }
3148
+ const progressRegex = /^(?:100|[1-9]?\d(?:\.\d+)?)\s*%$/;
3149
+ if (progressRegex.test(value)) {
3150
+ value = parseFloat(value);
3151
+ }
3008
3152
  if (!isEmpty(value)) {
3009
- const progressValue = Number(value);
3010
- if (!Number.isNaN(progressValue) && progressValue >= 0 && progressValue <= 100) {
3011
- return progressValue;
3153
+ let progressValue = Number(value);
3154
+ if (!Number.isNaN(progressValue)) {
3155
+ progressValue = Math.round(progressValue);
3156
+ if (progressValue >= 0 && progressValue <= 100) {
3157
+ return progressValue;
3158
+ }
3012
3159
  }
3013
3160
  }
3014
3161
  return null;
@@ -3442,12 +3589,14 @@ function appendRecord(aiTable, actions) {
3442
3589
  });
3443
3590
  }
3444
3591
  function appendField(aiTable, originField, actions) {
3445
- const lastFieldId = aiTable.fields().length > 0 ? aiTable.fields()[aiTable.fields().length - 1]._id : '';
3592
+ const fields = aiTable.gridData().fields;
3593
+ const lastFieldId = fields.length > 0 ? fields[fields.length - 1]._id : '';
3446
3594
  let defaultFieldValue;
3447
3595
  if (originField) {
3596
+ const fieldOptions = getFieldOptions(aiTable);
3448
3597
  defaultFieldValue = {
3449
3598
  ...originField,
3450
- name: createDefaultFieldName(aiTable, FieldOptions.find((item) => item.type === originField.type)),
3599
+ name: createDefaultFieldName(aiTable, fieldOptions.find((item) => item.type === originField.type)),
3451
3600
  _id: idCreator()
3452
3601
  };
3453
3602
  }
@@ -3538,15 +3687,15 @@ const getVisibleRangeInfo = (coordinate, scrollState) => {
3538
3687
  columnStopIndex
3539
3688
  };
3540
3689
  };
3541
- const scrollMax = (coordinate, visibleColumns) => {
3542
- const scrollMaxWidth = visibleColumns.reduce((pre, cur) => pre + getFieldOptionByField(cur)?.width, AI_TABLE_ROW_HEAD_WIDTH);
3690
+ const scrollMax = (aiTable, coordinate, visibleColumns) => {
3691
+ const scrollMaxWidth = visibleColumns.reduce((pre, cur) => pre + getFieldOptionByField(aiTable, cur)?.width, AI_TABLE_ROW_HEAD_WIDTH);
3543
3692
  const scrollMaxHeight = coordinate.getRowOffset(coordinate.rowCount - 1) + 32;
3544
3693
  return { scrollMaxWidth, scrollMaxHeight };
3545
3694
  };
3546
3695
 
3547
- const getMousePosition = (x, y, coordinate, fields, context, _targetName) => {
3696
+ const getMousePosition = (aiTable, x, y, coordinate, fields, context, _targetName) => {
3548
3697
  const { scrollTop, scrollLeft } = context.scrollState();
3549
- const { scrollMaxWidth, scrollMaxHeight } = scrollMax(coordinate, fields);
3698
+ const { scrollMaxWidth, scrollMaxHeight } = scrollMax(aiTable, coordinate, fields);
3550
3699
  const offsetTop = scrollTop + y;
3551
3700
  const rowIndex = coordinate.getRowStartIndex(offsetTop);
3552
3701
  const offsetLeft = isWithinFrozenColumnBoundary(x, coordinate.frozenColumnWidth) ? x : scrollLeft + x;
@@ -5079,7 +5228,7 @@ class AITableCellLink {
5079
5228
  return;
5080
5229
  const { context } = aiTable;
5081
5230
  const { x, y } = pos;
5082
- const curMousePosition = getMousePosition(x, y, coordinate, AITable.getVisibleFields(aiTable), context, targetName);
5231
+ const curMousePosition = getMousePosition(aiTable, x, y, coordinate, AITable.getVisibleFields(aiTable), context, targetName);
5083
5232
  handleMouseStyle(AI_TABLE_FIELD_HEAD_MORE, curMousePosition.areaType, coordinate.container);
5084
5233
  }
5085
5234
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableCellLink, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
@@ -5104,927 +5253,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
5104
5253
  }]
5105
5254
  }] });
5106
5255
 
5107
- var cellComponents = /*#__PURE__*/Object.freeze({
5108
- __proto__: null,
5109
- AITableCellLink: AITableCellLink
5110
- });
5111
-
5112
- const componentMap = {};
5113
- Object.values(cellComponents).forEach((cellComponent) => {
5114
- componentMap[cellComponent.fieldType] = cellComponent;
5115
- });
5116
-
5117
- function getHoverCell(aiTable) {
5118
- const pointPosition = aiTable.context.pointPosition();
5119
- const { fieldId, recordId } = getDetailByTargetName(pointPosition.realTargetName) ?? {};
5120
- if (!recordId || !fieldId) {
5121
- return;
5122
- }
5123
- const record = aiTable.recordsMap()[recordId];
5124
- const field = aiTable.fieldsMap()[fieldId];
5125
- if (!record || !field || !recordId || !fieldId) {
5126
- return;
5127
- }
5128
- const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, fieldId]);
5129
- const transformValue = transformCellValue(aiTable, field, cellValue) || {};
5130
- if (Object.keys(transformValue).length === 0) {
5131
- return;
5132
- }
5133
- const renderComponentDefinition = componentMap[field?.type];
5134
- if (!renderComponentDefinition) {
5135
- return;
5136
- }
5137
- return {
5138
- field,
5139
- recordId,
5140
- fieldId,
5141
- renderComponentDefinition
5142
- };
5143
- }
5144
-
5145
- class AITableGridEventService {
5146
- constructor() {
5147
- this.dblClickEvent$ = new Subject();
5148
- this.mousedownEvent$ = new Subject();
5149
- this.mouseoverEvent$ = new Subject();
5150
- this.globalMouseoverEvent$ = new Subject();
5151
- this.globalMousedownEvent$ = new Subject();
5152
- this.destroyRef = inject(DestroyRef);
5153
- this.thyPopover = inject(ThyPopover);
5154
- }
5155
- initialize(aiTable, aiFieldRenderers) {
5156
- this.aiTable = aiTable;
5157
- this.aiFieldRenderers = aiFieldRenderers;
5158
- }
5159
- registerEvents(element) {
5160
- fromEvent(element, 'dblclick', { passive: true })
5161
- .pipe(takeUntilDestroyed(this.destroyRef))
5162
- .subscribe((event) => {
5163
- this.dblClickEvent$.next(event);
5164
- });
5165
- fromEvent(element, 'mouseover', { passive: true })
5166
- .pipe(debounceTime(80), takeUntilDestroyed(this.destroyRef))
5167
- .subscribe((event) => {
5168
- this.mouseoverEvent$.next(event);
5169
- });
5170
- fromEvent(document, 'mouseover', { passive: true })
5171
- .pipe(takeUntilDestroyed(this.destroyRef))
5172
- .subscribe((event) => {
5173
- this.globalMouseoverEvent$.next(event);
5174
- });
5175
- fromEvent(element, 'mousedown', { passive: true })
5176
- .pipe(takeUntilDestroyed(this.destroyRef))
5177
- .subscribe((event) => {
5178
- this.mousedownEvent$.next(event);
5179
- });
5180
- fromEvent(document, 'mousedown', { passive: true })
5181
- .pipe(takeUntilDestroyed(this.destroyRef))
5182
- .subscribe((event) => {
5183
- this.globalMousedownEvent$.next(event);
5184
- });
5185
- }
5186
- getEditorComponent(type) {
5187
- const filedRenderSchema = this.aiFieldRenderers && this.aiFieldRenderers[type];
5188
- if (filedRenderSchema && filedRenderSchema.editor) {
5189
- return {
5190
- component: filedRenderSchema.editor,
5191
- isInternalComponent: false
5192
- };
5193
- }
5194
- return {
5195
- component: GRID_CELL_EDITOR_MAP[type],
5196
- isInternalComponent: true
5197
- };
5198
- }
5199
- openEdit(cellDom) {
5200
- const { x, y, width, height } = cellDom.getBoundingClientRect();
5201
- const fieldId = cellDom.getAttribute('fieldId');
5202
- const recordId = cellDom.getAttribute('recordId');
5203
- const { component } = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
5204
- const ref = this.thyPopover.open(component, {
5205
- origin: cellDom,
5206
- originPosition: {
5207
- x: x - 1,
5208
- y: y + 1,
5209
- width: width + 2,
5210
- height: height + 2
5211
- },
5212
- width: width + 1 + 'px',
5213
- height: height + 2 + 'px',
5214
- placement: 'top',
5215
- offset: -(height + 4),
5216
- minWidth: width,
5217
- initialState: {
5218
- fieldId: fieldId,
5219
- recordId: recordId,
5220
- aiTable: this.aiTable
5221
- },
5222
- panelClass: 'grid-cell-editor',
5223
- outsideClosable: false,
5224
- hasBackdrop: false,
5225
- manualClosure: true,
5226
- animationDisabled: true,
5227
- autoAdaptive: true
5228
- });
5229
- return ref;
5230
- }
5231
- getOriginPosition(aiTable, options) {
5232
- const { container, coordinate, recordId, fieldId, isHoverEdit } = options;
5233
- const { scrollState } = aiTable.context;
5234
- const { rowHeight, columnCount } = coordinate;
5235
- const cell = [recordId, fieldId];
5236
- const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, cell);
5237
- const originX = coordinate.getColumnOffset(columnIndex);
5238
- const originY = coordinate.getRowOffset(rowIndex);
5239
- const columnWidth = coordinate.getColumnWidth(columnIndex);
5240
- const { width: originWidth, offset: originOffset } = getCellHorizontalPosition({
5241
- columnWidth,
5242
- columnIndex,
5243
- columnCount
5244
- });
5245
- const originRect = container.getBoundingClientRect();
5246
- const isFrozenColumn = AITable.isFrozenColumn(aiTable, columnIndex);
5247
- const scrollLeft = isFrozenColumn ? 0 : scrollState().scrollLeft;
5248
- const scrollTop = scrollState().scrollTop;
5249
- const originPosition = {
5250
- x: originX + originOffset - scrollLeft + originRect.x,
5251
- y: originY - scrollTop + originRect.y,
5252
- width: originWidth,
5253
- height: rowHeight
5254
- };
5255
- let x = originPosition.x + getEditorBoxOffset();
5256
- let y = originPosition.y + getEditorBoxOffset();
5257
- let width = getEditorSpace(originPosition.width);
5258
- let height = getEditorSpace(originPosition.height);
5259
- // hover 编辑组件无边框
5260
- if (isHoverEdit) {
5261
- x = originPosition.x + getHoverEditorBoxOffset();
5262
- y = originPosition.y + getHoverEditorBoxOffset();
5263
- width = getHoverEditorSpace(originPosition.width);
5264
- height = getHoverEditorSpace(originPosition.height);
5265
- }
5266
- return {
5267
- ...originPosition,
5268
- x: x,
5269
- y: y,
5270
- width: width,
5271
- height: height
5272
- };
5273
- }
5274
- openCellEditor(aiTable, options) {
5275
- const { container, recordId, fieldId, isHoverEdit, references } = options;
5276
- const { component, isInternalComponent } = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
5277
- const offsetOriginPosition = this.getOriginPosition(aiTable, options);
5278
- this.cellEditorPopoverRef = this.thyPopover.open(component, {
5279
- viewContainerRef: isInternalComponent ? undefined : options?.viewContainerRef,
5280
- origin: container,
5281
- originPosition: offsetOriginPosition,
5282
- width: offsetOriginPosition.width + 'px',
5283
- height: offsetOriginPosition.height + 'px',
5284
- minWidth: offsetOriginPosition.width + 'px',
5285
- placement: 'bottom',
5286
- offset: -offsetOriginPosition.height,
5287
- initialState: {
5288
- fieldId: fieldId,
5289
- recordId: recordId,
5290
- references,
5291
- aiTable: aiTable
5292
- },
5293
- panelClass: 'grid-cell-editor',
5294
- outsideClosable: false,
5295
- hasBackdrop: false,
5296
- manualClosure: true,
5297
- animationDisabled: true,
5298
- autoAdaptive: true
5299
- });
5300
- if (this.cellEditorPopoverRef) {
5301
- const wheelEvent = fromEvent(this.cellEditorPopoverRef.componentInstance.elementRef.nativeElement, 'wheel').subscribe((event) => {
5302
- const field = aiTable.fieldsMap()[fieldId];
5303
- if (field.type === AITableFieldType.text || field.type === AITableFieldType.richText) {
5304
- return;
5305
- }
5306
- event.preventDefault();
5307
- this.aiTable.context?.scrollAction({
5308
- deltaX: event.deltaX,
5309
- deltaY: event.deltaY,
5310
- shiftKey: event.shiftKey,
5311
- callback: () => {
5312
- const originPosition = this.getOriginPosition(aiTable, options);
5313
- const positionStrategy = this.cellEditorPopoverRef
5314
- .getOverlayRef()
5315
- .getConfig().positionStrategy;
5316
- positionStrategy.setOrigin(originPosition);
5317
- positionStrategy.apply();
5318
- }
5319
- });
5320
- });
5321
- this.cellEditorPopoverRef.afterClosed().subscribe(() => {
5322
- wheelEvent.unsubscribe();
5323
- this.cellEditorPopoverRef = null;
5324
- });
5325
- this.cellEditorPopoverRef.componentInstance.updateFieldValue.subscribe((value) => {
5326
- options.updateFieldValue(value);
5327
- });
5328
- }
5329
- return this.cellEditorPopoverRef;
5330
- }
5331
- closeCellEditor() {
5332
- if (this.cellEditorPopoverRef) {
5333
- this.cellEditorPopoverRef.close();
5334
- this.cellEditorPopoverRef = null;
5335
- }
5336
- }
5337
- getCurrentEditCell() {
5338
- if (this.cellEditorPopoverRef) {
5339
- const recordId = this.cellEditorPopoverRef.componentInstance?.recordId;
5340
- const fieldId = this.cellEditorPopoverRef.componentInstance?.fieldId;
5341
- if (recordId && fieldId) {
5342
- return {
5343
- recordId,
5344
- fieldId
5345
- };
5346
- }
5347
- return null;
5348
- }
5349
- return null;
5350
- }
5351
- openContextMenu(aiTable, options) {
5352
- const { origin, position, menuItems, targetName, viewContainerRef } = options;
5353
- const ref = this.thyPopover.open(AITableContextMenu, {
5354
- origin: origin,
5355
- originPosition: position,
5356
- placement: 'bottomLeft',
5357
- insideClosable: true,
5358
- viewContainerRef,
5359
- initialState: {
5360
- aiTable,
5361
- menuItems,
5362
- targetName,
5363
- position
5364
- }
5365
- });
5366
- return ref;
5367
- }
5368
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5369
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService }); }
5370
- }
5371
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, decorators: [{
5372
- type: Injectable
5373
- }] });
5374
-
5375
- class AITableGridBase {
5376
- constructor() {
5377
- this.aiRecords = model.required();
5378
- this.aiFields = model.required();
5379
- this.aiContextMenuItems = input([]);
5380
- this.aiFieldConfig = input();
5381
- this.aiReadonly = input();
5382
- this.aiPlugins = input();
5383
- this.aiReferences = input.required();
5384
- this.aiBuildRenderDataFn = input();
5385
- this.aiKeywords = input();
5386
- this.AITableFieldType = AITableFieldType;
5387
- this.AITableSelectOptionStyle = AITableSelectOptionStyle;
5388
- this.isSelectedAll = computed(() => {
5389
- return this.aiTable.selection().selectedRecords.size === this.aiRecords().length;
5390
- });
5391
- this.aiTableInitialized = output();
5392
- this.aiAddRecord = output();
5393
- this.aiAddField = output();
5394
- this.aiMoveField = output();
5395
- this.aiUpdateFieldValue = output();
5396
- this.aiSetField = output();
5397
- this.fieldMenus = computed(() => {
5398
- return this.aiFieldConfig()?.fieldMenus || [];
5399
- });
5400
- this.gridData = computed(() => {
5401
- if (this.aiBuildRenderDataFn && this.aiBuildRenderDataFn() && this.aiTable) {
5402
- return this.aiBuildRenderDataFn()(this.aiTable);
5403
- }
5404
- return {
5405
- records: this.aiRecords(),
5406
- fields: this.aiFields()
5407
- };
5408
- });
5409
- this.ngZone = inject(NgZone);
5410
- this.elementRef = inject(ElementRef);
5411
- this.destroyRef = inject(DestroyRef);
5412
- this.aiTableGridFieldService = inject(AITableGridFieldService);
5413
- this.aiTableGridEventService = inject(AITableGridEventService);
5414
- this.aiTableGridSelectionService = inject(AITableGridSelectionService);
5415
- }
5416
- ngOnInit() {
5417
- this.initAITable();
5418
- this.initService();
5419
- }
5420
- initAITable() {
5421
- this.aiTable = createAITable(this.aiRecords, this.aiFields, this.gridData);
5422
- this.aiPlugins()?.forEach((plugin) => {
5423
- this.aiTable = plugin(this.aiTable);
5424
- });
5425
- this.aiTableInitialized.emit(this.aiTable);
5426
- }
5427
- initService() {
5428
- this.aiTableGridEventService.initialize(this.aiTable, this.aiFieldConfig()?.fieldRenderers);
5429
- this.aiTableGridSelectionService.initialize(this.aiTable);
5430
- this.aiTableGridEventService.registerEvents(this.elementRef.nativeElement);
5431
- this.aiTableGridFieldService.initAIFieldConfig(this.aiFieldConfig());
5432
- AI_TABLE_GRID_FIELD_SERVICE_MAP.set(this.aiTable, this.aiTableGridFieldService);
5433
- }
5434
- addRecord() {
5435
- const records = this.aiRecords();
5436
- const recordCount = records.length;
5437
- this.aiAddRecord.emit({
5438
- originId: recordCount > 0 ? records[records.length - 1]._id : ''
5439
- });
5440
- }
5441
- selectRecord(recordId) {
5442
- this.aiTableGridSelectionService.selectRecord(recordId);
5443
- }
5444
- toggleSelectAll(checked) {
5445
- this.aiTableGridSelectionService.toggleSelectAll(checked);
5446
- }
5447
- addField(gridColumnBlank, position) {
5448
- const field = createDefaultField(this.aiTable, AITableFieldType.text);
5449
- const popoverRef = this.aiTableGridFieldService.editFieldProperty(this.aiTable, {
5450
- field,
5451
- isUpdate: false,
5452
- origin: gridColumnBlank,
5453
- position
5454
- });
5455
- if (popoverRef && !this.aiFieldConfig()?.fieldSettingComponent) {
5456
- popoverRef.componentInstance.addField.subscribe((defaultValue) => {
5457
- const fields = this.gridData().fields;
5458
- const fieldCount = fields.length;
5459
- this.aiAddField.emit({
5460
- originId: fieldCount > 0 ? fields[fields.length - 1]._id : '',
5461
- defaultValue
5462
- });
5463
- });
5464
- }
5465
- }
5466
- subscribeEvents() {
5467
- this.ngZone.runOutsideAngular(() => {
5468
- this.aiTableGridEventService.dblClickEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
5469
- this.dblClick(event);
5470
- });
5471
- this.aiTableGridEventService.mousedownEvent$
5472
- .pipe(mergeWith(this.aiTableGridEventService.globalMousedownEvent$), takeUntilDestroyed(this.destroyRef))
5473
- .subscribe((event) => {
5474
- this.aiTableGridSelectionService.updateSelect(event);
5475
- });
5476
- this.aiTableGridEventService.mouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
5477
- this.mouseoverHandle(event);
5478
- });
5479
- this.aiTableGridEventService.globalMouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
5480
- this.closeHoverCellEditor(event);
5481
- });
5482
- });
5483
- }
5484
- dblClick(event) {
5485
- const cellDom = event.target.closest('.grid-cell');
5486
- const type = cellDom && cellDom.getAttribute('type');
5487
- if (type && DBL_CLICK_EDIT_TYPE.includes(type)) {
5488
- this.aiTableGridEventService.openEdit(cellDom);
5489
- }
5490
- }
5491
- mouseoverHandle(event) {
5492
- if (this.mouseoverRef) {
5493
- this.mouseoverRef?.close();
5494
- }
5495
- const cellDom = event.target.closest('.grid-cell');
5496
- const type = cellDom && cellDom.getAttribute('type');
5497
- if (type && MOUSEOVER_EDIT_TYPE.includes(type)) {
5498
- this.mouseoverRef = this.aiTableGridEventService.openEdit(cellDom);
5499
- }
5500
- }
5501
- closeHoverCellEditor(e) {
5502
- if (this.mouseoverRef) {
5503
- const hasGrid = e.target && e.target.closest('.ai-table-grid');
5504
- const hasCellEditor = e.target && e.target.closest('.grid-cell-editor');
5505
- if (!hasGrid && !hasCellEditor) {
5506
- this.mouseoverRef.close();
5507
- }
5508
- }
5509
- }
5510
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5511
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableGridBase, isStandalone: true, selector: "ai-table-grid-base", inputs: { aiRecords: { classPropertyName: "aiRecords", publicName: "aiRecords", isSignal: true, isRequired: true, transformFunction: null }, aiFields: { classPropertyName: "aiFields", publicName: "aiFields", isSignal: true, isRequired: true, transformFunction: null }, aiContextMenuItems: { classPropertyName: "aiContextMenuItems", publicName: "aiContextMenuItems", isSignal: true, isRequired: false, transformFunction: null }, aiFieldConfig: { classPropertyName: "aiFieldConfig", publicName: "aiFieldConfig", isSignal: true, isRequired: false, transformFunction: null }, aiReadonly: { classPropertyName: "aiReadonly", publicName: "aiReadonly", isSignal: true, isRequired: false, transformFunction: null }, aiPlugins: { classPropertyName: "aiPlugins", publicName: "aiPlugins", isSignal: true, isRequired: false, transformFunction: null }, aiReferences: { classPropertyName: "aiReferences", publicName: "aiReferences", isSignal: true, isRequired: true, transformFunction: null }, aiBuildRenderDataFn: { classPropertyName: "aiBuildRenderDataFn", publicName: "aiBuildRenderDataFn", isSignal: true, isRequired: false, transformFunction: null }, aiKeywords: { classPropertyName: "aiKeywords", publicName: "aiKeywords", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiRecords: "aiRecordsChange", aiFields: "aiFieldsChange", aiTableInitialized: "aiTableInitialized", aiAddRecord: "aiAddRecord", aiAddField: "aiAddField", aiMoveField: "aiMoveField", aiUpdateFieldValue: "aiUpdateFieldValue", aiSetField: "aiSetField" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5512
- }
5513
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, decorators: [{
5514
- type: Component,
5515
- args: [{
5516
- selector: 'ai-table-grid-base',
5517
- template: '',
5518
- standalone: true,
5519
- changeDetection: ChangeDetectionStrategy.OnPush
5520
- }]
5521
- }] });
5522
-
5523
- class AITableDomGrid extends AITableGridBase {
5524
- ngOnInit() {
5525
- super.ngOnInit();
5526
- this.subscribeEvents();
5527
- }
5528
- openFieldMenu(e, field, fieldAction) {
5529
- const moreBtn = e.target.closest('.grid-field-action');
5530
- this.aiTableGridFieldService.openFieldMenu(this.aiTable, {
5531
- origin: moreBtn,
5532
- editOrigin: fieldAction,
5533
- fieldId: field._id,
5534
- fieldMenus: this.fieldMenus()
5535
- });
5536
- }
5537
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
5538
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableDomGrid, isStandalone: true, selector: "ai-table-dom-grid", host: { classAttribute: "ai-table-grid ai-table-dom-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], usesInheritance: true, ngImport: i0, template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SelectOptionPipe, name: "selectOption" }, { kind: "pipe", type: SelectOptionsPipe, name: "selectOptions" }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "ngmodule", type: ThyPopoverModule }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyRate, selector: "thy-rate", inputs: ["thyCount", "thyDisabled", "thyAllowHalf", "thyAllowClear", "thyTooltips", "thyIconTemplate"], outputs: ["thyItemHoverChange"] }, { kind: "component", type: ThyProgress, selector: "thy-progress", inputs: ["thyType", "thySize", "thyValue", "thyMax", "thyTips", "thyShape", "thyGapDegree", "thyGapPosition", "thyStrokeWidth"] }, { kind: "pipe", type: ThyDatePickerFormatPipe, name: "thyDatePickerFormat" }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyCheckboxModule }, { kind: "component", type: i3$1.ThyCheckbox, selector: "thy-checkbox,[thy-checkbox],[thyCheckbox]", inputs: ["thyIndeterminate"] }, { kind: "ngmodule", type: ThyAvatarModule }, { kind: "component", type: i4.ThyAvatar, selector: "thy-avatar", inputs: ["thyShowName", "thySrc", "thyName", "thySize", "thyShowRemove", "thyRemovable", "thyImgClass", "thyDisabled", "thyLoading", "thyFetchPriority"], outputs: ["thyOnRemove", "thyRemove", "thyError"] }, { kind: "component", type: i4.ThyAvatarList, selector: "thy-avatar-list", inputs: ["thyMode", "thyAvatarSize"] }, { kind: "pipe", type: IsSelectRecordPipe, name: "isSelectRecord" }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "pipe", type: UserPipe, name: "user" }, { kind: "pipe", type: SelectSettingPipe, name: "selectSetting" }, { kind: "pipe", type: MemberSettingPipe, name: "memberSetting" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5539
- }
5540
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, decorators: [{
5541
- type: Component,
5542
- args: [{ selector: 'ai-table-dom-grid', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
5543
- class: 'ai-table-grid ai-table-dom-grid'
5544
- }, imports: [
5545
- NgClass,
5546
- NgComponentOutlet,
5547
- CommonModule,
5548
- FormsModule,
5549
- SelectOptionPipe,
5550
- SelectOptionsPipe,
5551
- ThyTag,
5552
- ThyPopoverModule,
5553
- ThyIcon,
5554
- ThyRate,
5555
- ThyProgress,
5556
- AITableFieldSetting,
5557
- ThyDatePickerFormatPipe,
5558
- ThyFlexibleText,
5559
- ThyStopPropagationDirective,
5560
- AITableFieldMenu,
5561
- ThyAction,
5562
- ThyDropdownDirective,
5563
- ThyDropdownMenuComponent,
5564
- ThyCheckboxModule,
5565
- ProgressEditorComponent,
5566
- ThyAvatarModule,
5567
- NgTemplateOutlet,
5568
- IsSelectRecordPipe,
5569
- ProgressEditorComponent,
5570
- SelectOptionComponent,
5571
- UserPipe,
5572
- SelectSettingPipe,
5573
- MemberSettingPipe
5574
- ], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n" }]
5575
- }] });
5576
-
5577
- class KoStage {
5578
- constructor() {
5579
- this.config = input();
5580
- this.koMouseover = new EventEmitter();
5581
- this.koMousemove = new EventEmitter();
5582
- this.koMouseout = new EventEmitter();
5583
- this.koMouseenter = new EventEmitter();
5584
- this.koMouseleave = new EventEmitter();
5585
- this.koMousedown = new EventEmitter();
5586
- this.koMouseup = new EventEmitter();
5587
- this.koWheel = new EventEmitter();
5588
- this.koContextmenu = new EventEmitter();
5589
- this.koClick = new EventEmitter();
5590
- this.koDblclick = new EventEmitter();
5591
- this.koTouchstart = new EventEmitter();
5592
- this.koTouchmove = new EventEmitter();
5593
- this.koTouchend = new EventEmitter();
5594
- this.koTap = new EventEmitter();
5595
- this.koDbltap = new EventEmitter();
5596
- this.koDragstart = new EventEmitter();
5597
- this.koDragmove = new EventEmitter();
5598
- this.koDragend = new EventEmitter();
5599
- this.cacheProps = {};
5600
- this.nodeContainer = inject(ElementRef).nativeElement;
5601
- effect(() => {
5602
- if (this.config()) {
5603
- if (!this._stage) {
5604
- this.initStage();
5605
- }
5606
- this.updateNode(this.config());
5607
- }
5608
- });
5609
- }
5610
- ngOnInit() {
5611
- this.initStage();
5612
- }
5613
- getNode() {
5614
- return this._stage;
5615
- }
5616
- initStage() {
5617
- this._stage = new Stage({
5618
- ...this.config(),
5619
- container: this.nodeContainer
5620
- });
5621
- }
5622
- updateNode(config) {
5623
- const props = {
5624
- ...config,
5625
- ...createListener(this)
5626
- };
5627
- applyNodeProps(this, props, this.cacheProps);
5628
- this.cacheProps = props;
5629
- }
5630
- ngOnDestroy() {
5631
- this._stage?.destroy();
5632
- }
5633
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5634
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: KoStage, isStandalone: true, selector: "ko-stage", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { koMouseover: "koMouseover", koMousemove: "koMousemove", koMouseout: "koMouseout", koMouseenter: "koMouseenter", koMouseleave: "koMouseleave", koMousedown: "koMousedown", koMouseup: "koMouseup", koWheel: "koWheel", koContextmenu: "koContextmenu", koClick: "koClick", koDblclick: "koDblclick", koTouchstart: "koTouchstart", koTouchmove: "koTouchmove", koTouchend: "koTouchend", koTap: "koTap", koDbltap: "koDbltap", koDragstart: "koDragstart", koDragmove: "koDragmove", koDragend: "koDragend" }, providers: [
5635
- {
5636
- provide: KO_CONTAINER_TOKEN,
5637
- useExisting: KoStage
5638
- }
5639
- ], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5640
- }
5641
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, decorators: [{
5642
- type: Component,
5643
- args: [{
5644
- selector: 'ko-stage',
5645
- standalone: true,
5646
- template: `<ng-content></ng-content>`,
5647
- providers: [
5648
- {
5649
- provide: KO_CONTAINER_TOKEN,
5650
- useExisting: KoStage
5651
- }
5652
- ],
5653
- changeDetection: ChangeDetectionStrategy.OnPush
5654
- }]
5655
- }], ctorParameters: () => [], propDecorators: { koMouseover: [{
5656
- type: Output
5657
- }], koMousemove: [{
5658
- type: Output
5659
- }], koMouseout: [{
5660
- type: Output
5661
- }], koMouseenter: [{
5662
- type: Output
5663
- }], koMouseleave: [{
5664
- type: Output
5665
- }], koMousedown: [{
5666
- type: Output
5667
- }], koMouseup: [{
5668
- type: Output
5669
- }], koWheel: [{
5670
- type: Output
5671
- }], koContextmenu: [{
5672
- type: Output
5673
- }], koClick: [{
5674
- type: Output
5675
- }], koDblclick: [{
5676
- type: Output
5677
- }], koTouchstart: [{
5678
- type: Output
5679
- }], koTouchmove: [{
5680
- type: Output
5681
- }], koTouchend: [{
5682
- type: Output
5683
- }], koTap: [{
5684
- type: Output
5685
- }], koDbltap: [{
5686
- type: Output
5687
- }], koDragstart: [{
5688
- type: Output
5689
- }], koDragmove: [{
5690
- type: Output
5691
- }], koDragend: [{
5692
- type: Output
5693
- }] } });
5694
-
5695
- class KoComponent extends Component {
5696
- }
5697
-
5698
- const KoShapeTypes = {
5699
- Arc,
5700
- Arrow,
5701
- Circle,
5702
- Ellipse,
5703
- Image: Image$1,
5704
- Label,
5705
- Tag,
5706
- Line,
5707
- Path,
5708
- Rect,
5709
- RegularPolygon,
5710
- Ring,
5711
- Star,
5712
- Text,
5713
- TextPath,
5714
- Transformer,
5715
- Wedge,
5716
- Group,
5717
- Layer,
5718
- FastLayer
5719
- };
5720
-
5721
- class AITableIcon {
5722
- constructor() {
5723
- this.config = input.required();
5724
- this.groupConfig = computed(() => {
5725
- const { x, y, listening } = this.config();
5726
- return { x, y, listening };
5727
- });
5728
- this.squareShapeConfig = computed(() => {
5729
- const { name, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, strokeWidth = 1, background, cornerRadius, opacity } = this.config();
5730
- return {
5731
- name,
5732
- width: backgroundWidth || size,
5733
- height: backgroundHeight || size,
5734
- strokeWidth: strokeWidth,
5735
- fill: background || Colors.transparent,
5736
- cornerRadius,
5737
- opacity
5738
- };
5739
- });
5740
- this.iconConfig = computed(() => {
5741
- const { type, data, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, stroke, strokeWidth = 1, scaleX, scaleY, offsetX, offsetY, rotation, fill = Colors.gray600, transformsEnabled = 'position' } = this.config();
5742
- let pathData = data;
5743
- switch (type) {
5744
- case AITableCheckType.checked:
5745
- pathData = Check;
5746
- break;
5747
- case AITableCheckType.unchecked:
5748
- pathData = Unchecked;
5749
- break;
5750
- }
5751
- return {
5752
- x: backgroundWidth && (backgroundWidth - size * (scaleX || 1)) / 2,
5753
- y: backgroundHeight && (backgroundHeight - size * (scaleY || 1)) / 2,
5754
- data: pathData,
5755
- width: size,
5756
- height: size,
5757
- fill,
5758
- offsetX,
5759
- offsetY,
5760
- scaleX,
5761
- scaleY,
5762
- rotation,
5763
- stroke,
5764
- strokeWidth,
5765
- transformsEnabled,
5766
- perfectDrawEnabled: false,
5767
- listening: false
5768
- };
5769
- });
5770
- }
5771
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5772
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableIcon, isStandalone: true, selector: "ai-table-icon", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
5773
- <ko-group [config]="groupConfig()">
5774
- <ko-rect [config]="squareShapeConfig()"></ko-rect>
5775
- <ko-path [config]="iconConfig()"></ko-path>
5776
- </ko-group>
5777
- `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5778
- }
5779
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, decorators: [{
5780
- type: Component,
5781
- args: [{
5782
- selector: 'ai-table-icon',
5783
- template: `
5784
- <ko-group [config]="groupConfig()">
5785
- <ko-rect [config]="squareShapeConfig()"></ko-rect>
5786
- <ko-path [config]="iconConfig()"></ko-path>
5787
- </ko-group>
5788
- `,
5789
- standalone: true,
5790
- imports: [KoContainer, KoShape],
5791
- changeDetection: ChangeDetectionStrategy.OnPush
5792
- }]
5793
- }] });
5794
-
5795
- class AITableAddField {
5796
- constructor() {
5797
- this.config = input.required();
5798
- this.btnWidth = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
5799
- this.x = computed(() => {
5800
- const lastColumnWidth = this.config().coordinate.getColumnWidth(this.config().columnStopIndex);
5801
- const lastColumnOffset = this.config().coordinate.getColumnOffset(this.config().columnStopIndex);
5802
- return lastColumnWidth + lastColumnOffset;
5803
- });
5804
- this.rectConfig = computed(() => {
5805
- const { pointPosition: { targetName }, readonly } = this.config();
5806
- const fill = targetName === AI_TABLE_FIELD_ADD_BUTTON ? Colors.gray80 : Colors.white;
5807
- return {
5808
- name: generateTargetName({
5809
- targetName: AI_TABLE_FIELD_ADD_BUTTON,
5810
- fieldId: this.config().fields[this.config().columnStopIndex]._id,
5811
- mouseStyle: readonly ? 'default' : 'pointer'
5812
- }),
5813
- x: AI_TABLE_OFFSET,
5814
- y: AI_TABLE_OFFSET,
5815
- width: this.config().coordinate.containerWidth - this.x() < this.btnWidth
5816
- ? this.btnWidth
5817
- : this.config().coordinate.containerWidth - this.x(),
5818
- height: this.config().coordinate.rowInitSize,
5819
- stroke: Colors.gray200,
5820
- strokeWidth: 1,
5821
- listening: true,
5822
- fill
5823
- };
5824
- });
5825
- this.addIconConfig = computed(() => {
5826
- const { readonly } = this.config();
5827
- const offsetY = (this.config().coordinate.rowInitSize - AI_TABLE_ICON_COMMON_SIZE) / 2;
5828
- return {
5829
- x: AI_TABLE_CELL_PADDING,
5830
- y: offsetY,
5831
- data: AddOutlinedPath,
5832
- fill: Colors.gray600,
5833
- listening: false,
5834
- visible: isNil(readonly) ? true : !readonly
5835
- };
5836
- });
5837
- }
5838
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5839
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableAddField, isStandalone: true, selector: "ai-table-add-field", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
5840
- <ko-group [config]="{ x: x() }">
5841
- <ko-group>
5842
- <ko-rect [config]="rectConfig()"></ko-rect>
5843
- </ko-group>
5844
- <ko-group>
5845
- @if (addIconConfig().visible) {
5846
- <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
5847
- }
5848
- </ko-group>
5849
- </ko-group>
5850
- `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableIcon, selector: "ai-table-icon", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5851
- }
5852
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, decorators: [{
5853
- type: Component,
5854
- args: [{
5855
- selector: 'ai-table-add-field',
5856
- template: `
5857
- <ko-group [config]="{ x: x() }">
5858
- <ko-group>
5859
- <ko-rect [config]="rectConfig()"></ko-rect>
5860
- </ko-group>
5861
- <ko-group>
5862
- @if (addIconConfig().visible) {
5863
- <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
5864
- }
5865
- </ko-group>
5866
- </ko-group>
5867
- `,
5868
- standalone: true,
5869
- imports: [KoContainer, KoShape, AITableIcon],
5870
- changeDetection: ChangeDetectionStrategy.OnPush
5871
- }]
5872
- }] });
5873
-
5874
- /**
5875
- * 用于处理表格行或单元格的布局和绘制。
5876
- * 它提供了基本的布局信息(如位置、大小等),并定义了常用的绘图方法(如渲染缩进区域、添加新字段的空白区域等)。
5877
- * 该类继承自 Drawer,并被其他更具体的布局类(如 RecordRowLayout)扩展和使用
5878
- */
5879
- class Layout extends Drawer {
5880
- constructor() {
5881
- super(...arguments);
5882
- // 定义当前单元格或行的位置
5883
- this.x = 0;
5884
- this.y = 0;
5885
- // 行高
5886
- this.rowHeight = 0;
5887
- // 列宽
5888
- this.columnWidth = 0;
5889
- // 行索引
5890
- this.rowIndex = 0;
5891
- // 列索引
5892
- this.columnIndex = 0;
5893
- // 列数
5894
- this.columnCount = 0;
5895
- this.containerWidth = 0;
5896
- }
5897
- // 用于初始化或重置布局的基本属性。这个方法通常在每次渲染新的一行或单元格时调用,确保布局信息是最新的
5898
- init({ x, y, rowIndex, columnIndex, rowHeight, columnWidth, columnCount, containerWidth }) {
5899
- this.x = x;
5900
- this.y = y;
5901
- this.rowIndex = rowIndex;
5902
- this.columnIndex = columnIndex;
5903
- this.rowHeight = rowHeight;
5904
- this.columnWidth = columnWidth;
5905
- this.columnCount = columnCount;
5906
- this.containerWidth = containerWidth;
5907
- }
5908
- // 当前单元格是否是行的第一列
5909
- get isFirst() {
5910
- return this.columnIndex === 0;
5911
- }
5912
- // 当前单元格是否是行的最后一列
5913
- get isLast() {
5914
- return this.columnIndex === this.columnCount - 1;
5915
- }
5916
- renderAddFieldBlank({ isHoverRow, isCheckedRow }) {
5917
- const rowHeight = this.rowHeight;
5918
- const fill = isCheckedRow ? this.colors.itemActiveBgColor : isHoverRow ? this.colors.gray80 : this.colors.transparent;
5919
- const addFieldBlankX = this.x + this.columnWidth + AI_TABLE_OFFSET;
5920
- this.rect({
5921
- x: addFieldBlankX,
5922
- y: this.y + AI_TABLE_OFFSET,
5923
- width: this.containerWidth - addFieldBlankX < AI_TABLE_FIELD_ADD_BUTTON_WIDTH
5924
- ? AI_TABLE_FIELD_ADD_BUTTON_WIDTH
5925
- : this.containerWidth - addFieldBlankX,
5926
- height: rowHeight,
5927
- fill
5928
- });
5929
- }
5930
- }
5931
-
5932
- class AddRowLayout extends Layout {
5933
- renderAddFieldBlank({ isHoverRow, isCheckedRow }) {
5934
- super.renderAddFieldBlank({ isHoverRow, isCheckedRow });
5935
- const rowHeight = this.rowHeight;
5936
- const defaultWidth = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
5937
- const width = this.containerWidth - this.x < defaultWidth ? defaultWidth : this.containerWidth - this.x;
5938
- this.line({
5939
- x: this.x + this.columnWidth,
5940
- y: this.y,
5941
- points: [0, rowHeight, width, rowHeight],
5942
- stroke: this.colors.gray200
5943
- });
5944
- }
5945
- renderCell({ width, isHoverRow }) {
5946
- const x = this.x;
5947
- const y = this.y;
5948
- const rowHeight = this.rowHeight;
5949
- const fill = isHoverRow ? this.colors.gray80 : this.colors.transparent;
5950
- this.rect({
5951
- x,
5952
- y: y + AI_TABLE_OFFSET,
5953
- width: width,
5954
- height: rowHeight,
5955
- fill
5956
- });
5957
- this.line({
5958
- x,
5959
- y: y + rowHeight,
5960
- points: [0, 0, width, 0],
5961
- stroke: this.colors.gray200
5962
- });
5963
- }
5964
- renderFirstCell({ isHoverRow }) {
5965
- if (!this.isFirst)
5966
- return;
5967
- const y = this.y;
5968
- const rowHeight = this.rowHeight;
5969
- const columnWidth = this.columnWidth;
5970
- const frozenOffset = AI_TABLE_OFFSET;
5971
- const fill = isHoverRow ? this.colors.gray80 : this.colors.transparent;
5972
- this.rect({
5973
- x: frozenOffset,
5974
- y: y + AI_TABLE_OFFSET,
5975
- width: columnWidth + AI_TABLE_ROW_HEAD_WIDTH - frozenOffset + 1,
5976
- height: rowHeight,
5977
- fill
5978
- });
5979
- this.line({
5980
- x: frozenOffset,
5981
- y,
5982
- points: [0, rowHeight, columnWidth + AI_TABLE_ROW_HEAD_WIDTH - frozenOffset + 1, rowHeight],
5983
- stroke: this.colors.gray200
5984
- });
5985
- this.path({
5986
- x: AI_TABLE_CELL_PADDING,
5987
- y: y + (rowHeight - AI_TABLE_ICON_COMMON_SIZE) / 2 - AI_TABLE_OFFSET,
5988
- data: AddOutlinedPath,
5989
- size: AI_TABLE_ROW_HEAD_SIZE,
5990
- fill: this.colors.gray600
5991
- });
5992
- }
5993
- renderLastCell({ isHoverRow, isCheckedRow }) {
5994
- if (!this.isLast)
5995
- return;
5996
- const width = this.columnWidth;
5997
- if (!this.isFirst) {
5998
- this.renderCell({
5999
- width,
6000
- isHoverRow
6001
- });
6002
- }
6003
- this.renderAddFieldBlank({ isHoverRow, isCheckedRow });
6004
- }
6005
- renderCommonCell({ isHoverRow }) {
6006
- if (this.isFirst || this.isLast)
6007
- return;
6008
- this.renderCell({
6009
- width: this.columnWidth,
6010
- isHoverRow
6011
- });
6012
- }
6013
- render({ isHoverRow, isCheckedRow }) {
6014
- this.renderFirstCell({
6015
- isHoverRow
6016
- });
6017
- this.renderCommonCell({
6018
- isHoverRow
6019
- });
6020
- this.renderLastCell({
6021
- isHoverRow,
6022
- isCheckedRow
6023
- });
6024
- }
6025
- }
6026
- const addRowLayout = new AddRowLayout();
6027
-
6028
5256
  // 自动生成的图标常量文件
6029
5257
  const apk = `<?xml version="1.0" encoding="UTF-8"?>
6030
5258
  <svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
@@ -6367,293 +5595,1267 @@ const zip = `<?xml version="1.0" encoding="UTF-8"?>
6367
5595
  </g>
6368
5596
  </svg>`;
6369
5597
 
6370
- var fileIcons = /*#__PURE__*/Object.freeze({
6371
- __proto__: null,
6372
- apk: apk,
6373
- bak: bak,
6374
- bat: bat,
6375
- cs: cs,
6376
- css: css,
6377
- csv: csv,
6378
- defaultFile: defaultFile,
6379
- doc: doc,
6380
- exe: exe,
6381
- fla: fla,
6382
- html: html,
6383
- img: img,
6384
- ipa: ipa,
6385
- java: java,
6386
- js: js,
6387
- key: key,
6388
- mp3: mp3,
6389
- page: page,
6390
- pdf: pdf,
6391
- php: php,
6392
- ppt: ppt,
6393
- rar: rar,
6394
- snippet: snippet,
6395
- swf: swf,
6396
- ttf: ttf,
6397
- txt: txt,
6398
- video: video,
6399
- vss: vss,
6400
- xls: xls,
6401
- xsd: xsd,
6402
- zip: zip
6403
- });
5598
+ function getFileThumbnailSvgString(ext) {
5599
+ let result = 'defaultFile';
5600
+ switch (ext) {
5601
+ case 'doc':
5602
+ case 'docx':
5603
+ result = doc;
5604
+ break;
5605
+ case 'ppt':
5606
+ case 'pptx':
5607
+ result = ppt;
5608
+ break;
5609
+ case 'xls':
5610
+ case 'xlsx':
5611
+ result = xls;
5612
+ break;
5613
+ case 'css':
5614
+ case 'scss':
5615
+ case 'sass':
5616
+ case 'less':
5617
+ result = css;
5618
+ break;
5619
+ case 'png':
5620
+ case 'jpeg':
5621
+ case 'jpg':
5622
+ case 'gif':
5623
+ case 'bmp':
5624
+ case 'svg':
5625
+ result = img;
5626
+ break;
5627
+ case 'mp4':
5628
+ case 'mkv':
5629
+ case 'webm':
5630
+ case 'mov':
5631
+ case 'flv':
5632
+ case '3gp':
5633
+ case 'mpv':
5634
+ case 'avi':
5635
+ case 'mpeg':
5636
+ case 'wmv':
5637
+ result = video;
5638
+ break;
5639
+ case 'mp3':
5640
+ case 'wma':
5641
+ case 'wav':
5642
+ case 'ape':
5643
+ case 'flac':
5644
+ case 'ogg':
5645
+ case 'm4r':
5646
+ case 'm4a':
5647
+ result = mp3;
5648
+ break;
5649
+ case 'pdf':
5650
+ result = pdf;
5651
+ break;
5652
+ case 'txt':
5653
+ result = txt;
5654
+ break;
5655
+ case 'apk':
5656
+ result = apk;
5657
+ break;
5658
+ case 'bak':
5659
+ result = apk;
5660
+ break;
5661
+ case 'cs':
5662
+ result = cs;
5663
+ break;
5664
+ case 'csv':
5665
+ result = csv;
5666
+ break;
5667
+ case 'exe':
5668
+ result = exe;
5669
+ break;
5670
+ case 'fla':
5671
+ result = fla;
5672
+ break;
5673
+ case 'html':
5674
+ result = html;
5675
+ break;
5676
+ case 'ipa':
5677
+ result = ipa;
5678
+ break;
5679
+ case 'java':
5680
+ result = java;
5681
+ break;
5682
+ case 'js':
5683
+ result = js;
5684
+ break;
5685
+ case 'php':
5686
+ result = php;
5687
+ break;
5688
+ case 'rar':
5689
+ result = rar;
5690
+ break;
5691
+ case 'swf':
5692
+ result = swf;
5693
+ break;
5694
+ case 'ttf':
5695
+ result = ttf;
5696
+ break;
5697
+ case 'vss':
5698
+ result = vss;
5699
+ break;
5700
+ case 'xsd':
5701
+ result = xsd;
5702
+ break;
5703
+ case 'zip':
5704
+ result = zip;
5705
+ break;
5706
+ default:
5707
+ result = defaultFile;
5708
+ break;
5709
+ }
5710
+ return result;
5711
+ }
5712
+
5713
+ class KoStage {
5714
+ constructor() {
5715
+ this.config = input();
5716
+ this.koMouseover = new EventEmitter();
5717
+ this.koMousemove = new EventEmitter();
5718
+ this.koMouseout = new EventEmitter();
5719
+ this.koMouseenter = new EventEmitter();
5720
+ this.koMouseleave = new EventEmitter();
5721
+ this.koMousedown = new EventEmitter();
5722
+ this.koMouseup = new EventEmitter();
5723
+ this.koWheel = new EventEmitter();
5724
+ this.koContextmenu = new EventEmitter();
5725
+ this.koClick = new EventEmitter();
5726
+ this.koDblclick = new EventEmitter();
5727
+ this.koTouchstart = new EventEmitter();
5728
+ this.koTouchmove = new EventEmitter();
5729
+ this.koTouchend = new EventEmitter();
5730
+ this.koTap = new EventEmitter();
5731
+ this.koDbltap = new EventEmitter();
5732
+ this.koDragstart = new EventEmitter();
5733
+ this.koDragmove = new EventEmitter();
5734
+ this.koDragend = new EventEmitter();
5735
+ this.cacheProps = {};
5736
+ this.nodeContainer = inject(ElementRef).nativeElement;
5737
+ effect(() => {
5738
+ if (this.config()) {
5739
+ if (!this._stage) {
5740
+ this.initStage();
5741
+ }
5742
+ this.updateNode(this.config());
5743
+ }
5744
+ });
5745
+ }
5746
+ ngOnInit() {
5747
+ this.initStage();
5748
+ }
5749
+ getNode() {
5750
+ return this._stage;
5751
+ }
5752
+ initStage() {
5753
+ this._stage = new Stage({
5754
+ ...this.config(),
5755
+ container: this.nodeContainer
5756
+ });
5757
+ }
5758
+ updateNode(config) {
5759
+ const props = {
5760
+ ...config,
5761
+ ...createListener(this)
5762
+ };
5763
+ applyNodeProps(this, props, this.cacheProps);
5764
+ this.cacheProps = props;
5765
+ }
5766
+ ngOnDestroy() {
5767
+ this._stage?.destroy();
5768
+ }
5769
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5770
+ 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: [
5771
+ {
5772
+ provide: KO_CONTAINER_TOKEN,
5773
+ useExisting: KoStage
5774
+ }
5775
+ ], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5776
+ }
5777
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KoStage, decorators: [{
5778
+ type: Component,
5779
+ args: [{
5780
+ selector: 'ko-stage',
5781
+ standalone: true,
5782
+ template: `<ng-content></ng-content>`,
5783
+ providers: [
5784
+ {
5785
+ provide: KO_CONTAINER_TOKEN,
5786
+ useExisting: KoStage
5787
+ }
5788
+ ],
5789
+ changeDetection: ChangeDetectionStrategy.OnPush
5790
+ }]
5791
+ }], ctorParameters: () => [], propDecorators: { koMouseover: [{
5792
+ type: Output
5793
+ }], koMousemove: [{
5794
+ type: Output
5795
+ }], koMouseout: [{
5796
+ type: Output
5797
+ }], koMouseenter: [{
5798
+ type: Output
5799
+ }], koMouseleave: [{
5800
+ type: Output
5801
+ }], koMousedown: [{
5802
+ type: Output
5803
+ }], koMouseup: [{
5804
+ type: Output
5805
+ }], koWheel: [{
5806
+ type: Output
5807
+ }], koContextmenu: [{
5808
+ type: Output
5809
+ }], koClick: [{
5810
+ type: Output
5811
+ }], koDblclick: [{
5812
+ type: Output
5813
+ }], koTouchstart: [{
5814
+ type: Output
5815
+ }], koTouchmove: [{
5816
+ type: Output
5817
+ }], koTouchend: [{
5818
+ type: Output
5819
+ }], koTap: [{
5820
+ type: Output
5821
+ }], koDbltap: [{
5822
+ type: Output
5823
+ }], koDragstart: [{
5824
+ type: Output
5825
+ }], koDragmove: [{
5826
+ type: Output
5827
+ }], koDragend: [{
5828
+ type: Output
5829
+ }] } });
5830
+
5831
+ class KoComponent extends Component {
5832
+ }
5833
+
5834
+ const KoShapeTypes = {
5835
+ Arc,
5836
+ Arrow,
5837
+ Circle,
5838
+ Ellipse,
5839
+ Image: Image$1,
5840
+ Label,
5841
+ Tag,
5842
+ Line,
5843
+ Path,
5844
+ Rect,
5845
+ RegularPolygon,
5846
+ Ring,
5847
+ Star,
5848
+ Text,
5849
+ TextPath,
5850
+ Transformer,
5851
+ Wedge,
5852
+ Group,
5853
+ Layer,
5854
+ FastLayer
5855
+ };
5856
+
5857
+ class AITableActionIcon {
5858
+ constructor() {
5859
+ this.onClick = output();
5860
+ this.onMousemove = output();
5861
+ this.onMouseenter = output();
5862
+ this.onMouseleave = output();
5863
+ this.config = input.required();
5864
+ this.isHover = signal(false);
5865
+ this.groupConfig = computed(() => {
5866
+ const { x, y, listening } = this.config();
5867
+ return { x, y, listening };
5868
+ });
5869
+ this.squareShapeConfig = computed(() => {
5870
+ const { name, backgroundWidth, backgroundHeight, hoverFill, size = DEFAULT_ICON_SIZE, strokeWidth = 1, cornerRadius } = this.config();
5871
+ return {
5872
+ name,
5873
+ width: backgroundWidth || size,
5874
+ height: backgroundHeight || size,
5875
+ strokeWidth: strokeWidth,
5876
+ fill: hoverFill && this.isHover() ? hoverFill : Colors.transparent,
5877
+ opacity: hoverFill && this.isHover() ? 0.1 : 1,
5878
+ cornerRadius
5879
+ };
5880
+ });
5881
+ this.iconConfig = computed(() => {
5882
+ let { type, data, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, stroke, strokeWidth = 1, scaleX, scaleY, offsetX, offsetY, rotation, fill, hoverFill, transformsEnabled = 'position' } = this.config();
5883
+ fill = fill || Colors.gray600;
5884
+ let pathData = data;
5885
+ switch (type) {
5886
+ case AITableCheckType.checked:
5887
+ pathData = Check;
5888
+ break;
5889
+ case AITableCheckType.unchecked:
5890
+ pathData = Unchecked;
5891
+ break;
5892
+ }
5893
+ return {
5894
+ x: backgroundWidth && (backgroundWidth - size * (scaleX || 1)) / 2,
5895
+ y: backgroundHeight && (backgroundHeight - size * (scaleY || 1)) / 2,
5896
+ data: pathData,
5897
+ width: size,
5898
+ height: size,
5899
+ fill: hoverFill && this.isHover() ? hoverFill : fill,
5900
+ offsetX,
5901
+ offsetY,
5902
+ scaleX,
5903
+ scaleY,
5904
+ rotation,
5905
+ stroke,
5906
+ strokeWidth,
5907
+ transformsEnabled,
5908
+ perfectDrawEnabled: false,
5909
+ listening: false
5910
+ };
5911
+ });
5912
+ }
5913
+ koClick(e) {
5914
+ this.onClick.emit(e);
5915
+ }
5916
+ koMousemove(e) {
5917
+ e.event.cancelBubble = true;
5918
+ }
5919
+ koMouseenter(e) {
5920
+ this.onMouseenter.emit(e);
5921
+ this.isHover.set(true);
5922
+ const { coordinate } = this.config();
5923
+ setMouseStyle('pointer', coordinate.container);
5924
+ }
5925
+ koMouseleave(e) {
5926
+ this.onMouseleave.emit(e);
5927
+ this.isHover.set(false);
5928
+ const { coordinate } = this.config();
5929
+ setMouseStyle('default', coordinate.container);
5930
+ }
5931
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableActionIcon, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5932
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableActionIcon, isStandalone: true, selector: "ai-table-action-icon", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onClick: "onClick", onMousemove: "onMousemove", onMouseenter: "onMouseenter", onMouseleave: "onMouseleave" }, ngImport: i0, template: `
5933
+ <ko-group
5934
+ [config]="groupConfig()"
5935
+ (koClick)="koClick($event)"
5936
+ (koMousemove)="koMousemove($event)"
5937
+ (koMouseenter)="koMouseenter($event)"
5938
+ (koMouseleave)="koMouseleave($event)"
5939
+ >
5940
+ <ko-rect [config]="squareShapeConfig()"></ko-rect>
5941
+ <ko-path [config]="iconConfig()"></ko-path>
5942
+ </ko-group>
5943
+ `, 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 }); }
5944
+ }
5945
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableActionIcon, decorators: [{
5946
+ type: Component,
5947
+ args: [{
5948
+ selector: 'ai-table-action-icon',
5949
+ template: `
5950
+ <ko-group
5951
+ [config]="groupConfig()"
5952
+ (koClick)="koClick($event)"
5953
+ (koMousemove)="koMousemove($event)"
5954
+ (koMouseenter)="koMouseenter($event)"
5955
+ (koMouseleave)="koMouseleave($event)"
5956
+ >
5957
+ <ko-rect [config]="squareShapeConfig()"></ko-rect>
5958
+ <ko-path [config]="iconConfig()"></ko-path>
5959
+ </ko-group>
5960
+ `,
5961
+ standalone: true,
5962
+ imports: [KoContainer, KoShape],
5963
+ changeDetection: ChangeDetectionStrategy.OnPush
5964
+ }]
5965
+ }] });
5966
+
5967
+ class AITableCellAttachment {
5968
+ constructor() {
5969
+ this.config = input();
5970
+ this.attachments = computed(() => {
5971
+ const { render, aiTable, coordinate, field, recordId, readonly } = this.config();
5972
+ if (render) {
5973
+ const {} = aiTable;
5974
+ const { transformValue, references, columnWidth, rowHeight, style, zIndex } = render;
5975
+ if (!transformValue?.length) {
5976
+ return [];
5977
+ }
5978
+ const result = transformValue?.map((attachmentId, index) => {
5979
+ const itemWidth = AI_TABLE_FILE_ICON_SIZE + AI_TABLE_FIELD_ITEM_MARGIN_RIGHT;
5980
+ const currentX = AI_TABLE_CELL_PADDING + index * itemWidth + AI_TABLE_OFFSET;
5981
+ let currentY = (AI_TABLE_ROW_BLANK_HEIGHT - AI_TABLE_FILE_ICON_SIZE) / 2 + AI_TABLE_OFFSET;
5982
+ if (columnWidth != null) {
5983
+ // 当超出列宽时,不会渲染后续内容
5984
+ if (currentX >= columnWidth - AI_TABLE_ACTION_COMMON_SIZE - 2 * AI_TABLE_CELL_PADDING) {
5985
+ return null;
5986
+ }
5987
+ }
5988
+ const attachmentInfo = references.attachments[attachmentId];
5989
+ if (attachmentInfo) {
5990
+ const svgString = getFileThumbnailSvgString(attachmentInfo.addition.ext);
5991
+ const image = new Image();
5992
+ image.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
5993
+ return {
5994
+ // coordinate,
5995
+ // readonly,
5996
+ attachmentInfo,
5997
+ name: generateTargetName({
5998
+ targetName: AI_TABLE_CELL,
5999
+ fieldId: field._id,
6000
+ recordId,
6001
+ mouseStyle: readonly ? 'default' : 'pointer',
6002
+ source: attachmentInfo._id
6003
+ }),
6004
+ x: currentX,
6005
+ y: currentY,
6006
+ width: AI_TABLE_FILE_ICON_SIZE,
6007
+ height: AI_TABLE_FILE_ICON_SIZE,
6008
+ image,
6009
+ listening: true
6010
+ };
6011
+ }
6012
+ return null;
6013
+ }) || [];
6014
+ return result.filter((item) => !!item);
6015
+ }
6016
+ return [];
6017
+ });
6018
+ this.iconConfig = computed(() => {
6019
+ const { coordinate, render, field, recordId, readonly } = this.config();
6020
+ const offsetX = render.columnWidth - AI_TABLE_ACTION_COMMON_SIZE - AI_TABLE_ACTION_COMMON_RIGHT_PADDING;
6021
+ const offsetY = (coordinate.rowInitSize - AI_TABLE_ACTION_COMMON_SIZE) / 2;
6022
+ return {
6023
+ coordinate,
6024
+ readonly,
6025
+ name: generateTargetName({
6026
+ targetName: AI_TABLE_CELL,
6027
+ fieldId: field._id,
6028
+ recordId,
6029
+ source: AI_TABLE_CELL_ATTACHMENT_ADD,
6030
+ mouseStyle: readonly ? 'default' : 'pointer'
6031
+ }),
6032
+ x: offsetX,
6033
+ y: offsetY,
6034
+ data: AddOutlinedPath,
6035
+ fill: Colors.gray600,
6036
+ hoverFill: Colors.primary,
6037
+ backgroundWidth: AI_TABLE_ACTION_COMMON_SIZE,
6038
+ backgroundHeight: AI_TABLE_ACTION_COMMON_SIZE,
6039
+ cornerRadius: AI_TABLE_ACTION_COMMON_RADIUS,
6040
+ listening: true
6041
+ };
6042
+ });
6043
+ }
6044
+ static { this.fieldType = AITableFieldType.attachment; }
6045
+ addClick(e) {
6046
+ // e.event.cancelBubble = true;
6047
+ }
6048
+ attachmentClick(e) {
6049
+ // e.event.cancelBubble = true;
6050
+ }
6051
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableCellAttachment, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6052
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableCellAttachment, isStandalone: true, selector: "ai-table-attachments", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
6053
+ @for (attachment of attachments(); track attachment.attachmentInfo._id) {
6054
+ <ko-image [config]="attachment" (koClick)="attachmentClick($event)"></ko-image>
6055
+ }
6056
+ <ai-table-action-icon [config]="iconConfig()" (onClick)="addClick($event)"></ai-table-action-icon>
6057
+ `, isInline: true, dependencies: [{ kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableActionIcon, selector: "ai-table-action-icon", inputs: ["config"], outputs: ["onClick", "onMousemove", "onMouseenter", "onMouseleave"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6058
+ }
6059
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableCellAttachment, decorators: [{
6060
+ type: Component,
6061
+ args: [{
6062
+ selector: 'ai-table-attachments',
6063
+ template: `
6064
+ @for (attachment of attachments(); track attachment.attachmentInfo._id) {
6065
+ <ko-image [config]="attachment" (koClick)="attachmentClick($event)"></ko-image>
6066
+ }
6067
+ <ai-table-action-icon [config]="iconConfig()" (onClick)="addClick($event)"></ai-table-action-icon>
6068
+ `,
6069
+ standalone: true,
6070
+ imports: [KoContainer, KoShape, AITableActionIcon],
6071
+ changeDetection: ChangeDetectionStrategy.OnPush
6072
+ }]
6073
+ }] });
6074
+
6075
+ // TODO: components下的cells组件考虑移出 components ,这些组件都属于
6076
+
6077
+ var cellComponents = /*#__PURE__*/Object.freeze({
6078
+ __proto__: null,
6079
+ AITableCellAttachment: AITableCellAttachment,
6080
+ AITableCellLink: AITableCellLink
6081
+ });
6082
+
6083
+ const componentMap = {};
6084
+ Object.values(cellComponents).forEach((cellComponent) => {
6085
+ componentMap[cellComponent.fieldType] = cellComponent;
6086
+ });
6087
+
6088
+ function getHoverCell(aiTable) {
6089
+ const pointPosition = aiTable.context.pointPosition();
6090
+ const { fieldId, recordId } = getDetailByTargetName(pointPosition.realTargetName) ?? {};
6091
+ if (!recordId || !fieldId) {
6092
+ return;
6093
+ }
6094
+ const record = aiTable.recordsMap()[recordId];
6095
+ const field = aiTable.fieldsMap()[fieldId];
6096
+ if (!record || !field || !recordId || !fieldId) {
6097
+ return;
6098
+ }
6099
+ const renderComponentDefinition = componentMap[field?.type];
6100
+ if (!renderComponentDefinition) {
6101
+ return;
6102
+ }
6103
+ return {
6104
+ field,
6105
+ recordId,
6106
+ fieldId,
6107
+ renderComponentDefinition
6108
+ };
6109
+ }
6110
+
6111
+ class AITableGridEventService {
6112
+ constructor() {
6113
+ this.dblClickEvent$ = new Subject();
6114
+ this.mousedownEvent$ = new Subject();
6115
+ this.mouseoverEvent$ = new Subject();
6116
+ this.globalMouseoverEvent$ = new Subject();
6117
+ this.globalMousedownEvent$ = new Subject();
6118
+ this.destroyRef = inject(DestroyRef);
6119
+ this.thyPopover = inject(ThyPopover);
6120
+ }
6121
+ initialize(aiTable, aiFieldRenderers) {
6122
+ this.aiTable = aiTable;
6123
+ this.aiFieldRenderers = aiFieldRenderers;
6124
+ }
6125
+ registerEvents(element) {
6126
+ fromEvent(element, 'dblclick', { passive: true })
6127
+ .pipe(takeUntilDestroyed(this.destroyRef))
6128
+ .subscribe((event) => {
6129
+ this.dblClickEvent$.next(event);
6130
+ });
6131
+ fromEvent(element, 'mouseover', { passive: true })
6132
+ .pipe(debounceTime(80), takeUntilDestroyed(this.destroyRef))
6133
+ .subscribe((event) => {
6134
+ this.mouseoverEvent$.next(event);
6135
+ });
6136
+ fromEvent(document, 'mouseover', { passive: true })
6137
+ .pipe(takeUntilDestroyed(this.destroyRef))
6138
+ .subscribe((event) => {
6139
+ this.globalMouseoverEvent$.next(event);
6140
+ });
6141
+ fromEvent(element, 'mousedown', { passive: true })
6142
+ .pipe(takeUntilDestroyed(this.destroyRef))
6143
+ .subscribe((event) => {
6144
+ this.mousedownEvent$.next(event);
6145
+ });
6146
+ fromEvent(document, 'mousedown', { passive: true })
6147
+ .pipe(takeUntilDestroyed(this.destroyRef))
6148
+ .subscribe((event) => {
6149
+ this.globalMousedownEvent$.next(event);
6150
+ });
6151
+ }
6152
+ getEditorComponent(type) {
6153
+ const filedRenderSchema = this.aiFieldRenderers && this.aiFieldRenderers[type];
6154
+ if (filedRenderSchema && filedRenderSchema.editor) {
6155
+ return {
6156
+ component: filedRenderSchema.editor,
6157
+ isInternalComponent: false
6158
+ };
6159
+ }
6160
+ return {
6161
+ component: GRID_CELL_EDITOR_MAP[type],
6162
+ isInternalComponent: true
6163
+ };
6164
+ }
6165
+ openEdit(cellDom) {
6166
+ const { x, y, width, height } = cellDom.getBoundingClientRect();
6167
+ const fieldId = cellDom.getAttribute('fieldId');
6168
+ const recordId = cellDom.getAttribute('recordId');
6169
+ const { component } = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
6170
+ const ref = this.thyPopover.open(component, {
6171
+ origin: cellDom,
6172
+ originPosition: {
6173
+ x: x - 1,
6174
+ y: y + 1,
6175
+ width: width + 2,
6176
+ height: height + 2
6177
+ },
6178
+ width: width + 1 + 'px',
6179
+ height: height + 2 + 'px',
6180
+ placement: 'top',
6181
+ offset: -(height + 4),
6182
+ minWidth: width,
6183
+ initialState: {
6184
+ fieldId: fieldId,
6185
+ recordId: recordId,
6186
+ aiTable: this.aiTable
6187
+ },
6188
+ panelClass: 'grid-cell-editor',
6189
+ outsideClosable: false,
6190
+ hasBackdrop: false,
6191
+ manualClosure: true,
6192
+ animationDisabled: true,
6193
+ autoAdaptive: true
6194
+ });
6195
+ return ref;
6196
+ }
6197
+ getOriginPosition(aiTable, options) {
6198
+ const { container, coordinate, recordId, fieldId, isHoverEdit } = options;
6199
+ const { scrollState } = aiTable.context;
6200
+ const { rowHeight, columnCount } = coordinate;
6201
+ const cell = [recordId, fieldId];
6202
+ const { rowIndex, columnIndex } = AITable.getCellIndex(aiTable, cell);
6203
+ const originX = coordinate.getColumnOffset(columnIndex);
6204
+ const originY = coordinate.getRowOffset(rowIndex);
6205
+ const columnWidth = coordinate.getColumnWidth(columnIndex);
6206
+ const { width: originWidth, offset: originOffset } = getCellHorizontalPosition({
6207
+ columnWidth,
6208
+ columnIndex,
6209
+ columnCount
6210
+ });
6211
+ const originRect = container.getBoundingClientRect();
6212
+ const isFrozenColumn = AITable.isFrozenColumn(aiTable, columnIndex);
6213
+ const scrollLeft = isFrozenColumn ? 0 : scrollState().scrollLeft;
6214
+ const scrollTop = scrollState().scrollTop;
6215
+ const originPosition = {
6216
+ x: originX + originOffset - scrollLeft + originRect.x,
6217
+ y: originY - scrollTop + originRect.y,
6218
+ width: originWidth,
6219
+ height: rowHeight
6220
+ };
6221
+ let x = originPosition.x + getEditorBoxOffset();
6222
+ let y = originPosition.y + getEditorBoxOffset();
6223
+ let width = getEditorSpace(originPosition.width);
6224
+ let height = getEditorSpace(originPosition.height);
6225
+ // hover 编辑组件无边框
6226
+ if (isHoverEdit) {
6227
+ x = originPosition.x + getHoverEditorBoxOffset();
6228
+ y = originPosition.y + getHoverEditorBoxOffset();
6229
+ width = getHoverEditorSpace(originPosition.width);
6230
+ height = getHoverEditorSpace(originPosition.height);
6231
+ }
6232
+ return {
6233
+ ...originPosition,
6234
+ x: x,
6235
+ y: y,
6236
+ width: width,
6237
+ height: height
6238
+ };
6239
+ }
6240
+ openCellEditor(aiTable, options) {
6241
+ const { container, recordId, fieldId, isHoverEdit, references } = options;
6242
+ const { component, isInternalComponent } = this.getEditorComponent(this.aiTable.fieldsMap()[fieldId].type);
6243
+ const offsetOriginPosition = this.getOriginPosition(aiTable, options);
6244
+ this.cellEditorPopoverRef = this.thyPopover.open(component, {
6245
+ viewContainerRef: isInternalComponent ? undefined : options?.viewContainerRef,
6246
+ origin: container,
6247
+ originPosition: offsetOriginPosition,
6248
+ width: offsetOriginPosition.width + 'px',
6249
+ height: offsetOriginPosition.height + 'px',
6250
+ minWidth: offsetOriginPosition.width + 'px',
6251
+ placement: 'bottom',
6252
+ offset: -offsetOriginPosition.height,
6253
+ initialState: {
6254
+ fieldId: fieldId,
6255
+ recordId: recordId,
6256
+ references,
6257
+ aiTable: aiTable
6258
+ },
6259
+ panelClass: 'grid-cell-editor',
6260
+ outsideClosable: false,
6261
+ hasBackdrop: false,
6262
+ manualClosure: true,
6263
+ animationDisabled: true,
6264
+ autoAdaptive: true
6265
+ });
6266
+ if (this.cellEditorPopoverRef) {
6267
+ const wheelEvent = fromEvent(this.cellEditorPopoverRef.componentInstance.elementRef.nativeElement, 'wheel').subscribe((event) => {
6268
+ const field = aiTable.fieldsMap()[fieldId];
6269
+ if (field.type === AITableFieldType.text || field.type === AITableFieldType.richText) {
6270
+ return;
6271
+ }
6272
+ event.preventDefault();
6273
+ this.aiTable.context?.scrollAction({
6274
+ deltaX: event.deltaX,
6275
+ deltaY: event.deltaY,
6276
+ shiftKey: event.shiftKey,
6277
+ callback: () => {
6278
+ const originPosition = this.getOriginPosition(aiTable, options);
6279
+ const positionStrategy = this.cellEditorPopoverRef
6280
+ .getOverlayRef()
6281
+ .getConfig().positionStrategy;
6282
+ positionStrategy.setOrigin(originPosition);
6283
+ positionStrategy.apply();
6284
+ }
6285
+ });
6286
+ });
6287
+ this.cellEditorPopoverRef.afterClosed().subscribe(() => {
6288
+ wheelEvent.unsubscribe();
6289
+ this.cellEditorPopoverRef = null;
6290
+ });
6291
+ this.cellEditorPopoverRef.componentInstance.updateFieldValue.subscribe((value) => {
6292
+ options.updateFieldValue(value);
6293
+ });
6294
+ }
6295
+ return this.cellEditorPopoverRef;
6296
+ }
6297
+ closeCellEditor() {
6298
+ if (this.cellEditorPopoverRef) {
6299
+ this.cellEditorPopoverRef.close();
6300
+ this.cellEditorPopoverRef = null;
6301
+ }
6302
+ }
6303
+ getCurrentEditCell() {
6304
+ if (this.cellEditorPopoverRef) {
6305
+ const recordId = this.cellEditorPopoverRef.componentInstance?.recordId;
6306
+ const fieldId = this.cellEditorPopoverRef.componentInstance?.fieldId;
6307
+ if (recordId && fieldId) {
6308
+ return {
6309
+ recordId,
6310
+ fieldId
6311
+ };
6312
+ }
6313
+ return null;
6314
+ }
6315
+ return null;
6316
+ }
6317
+ openContextMenu(aiTable, options) {
6318
+ const { origin, position, menuItems, targetName, viewContainerRef } = options;
6319
+ const ref = this.thyPopover.open(AITableContextMenu, {
6320
+ origin: origin,
6321
+ originPosition: position,
6322
+ placement: 'bottomLeft',
6323
+ insideClosable: true,
6324
+ viewContainerRef,
6325
+ initialState: {
6326
+ aiTable,
6327
+ menuItems,
6328
+ targetName,
6329
+ position
6330
+ }
6331
+ });
6332
+ return ref;
6333
+ }
6334
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6335
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService }); }
6336
+ }
6337
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridEventService, decorators: [{
6338
+ type: Injectable
6339
+ }] });
6404
6340
 
6405
- function parseSVGToCanvasObjects(svgString) {
6406
- const parser = new DOMParser();
6407
- const svgDoc = parser.parseFromString(svgString, 'image/svg+xml');
6408
- const elements = svgDoc.querySelectorAll('path, polyline, polygon');
6409
- const canvasObjects = [];
6410
- elements.forEach((element) => {
6411
- let d;
6412
- if (element.tagName === 'path') {
6413
- d = element.getAttribute('d');
6414
- }
6415
- else if (element.tagName === 'polyline' || element.tagName === 'polygon') {
6416
- const points = element.getAttribute('points') || '';
6417
- const pointArray = points.split(/\s+|,/).filter(Boolean);
6418
- d = 'M' + pointArray[0] + ' ' + pointArray[1];
6419
- for (let i = 2; i < pointArray.length; i += 2) {
6420
- d += ' L' + pointArray[i] + ' ' + pointArray[i + 1];
6341
+ class AITableGridBase {
6342
+ constructor() {
6343
+ this.aiRecords = model.required();
6344
+ this.aiFields = model.required();
6345
+ this.aiContextMenuItems = input();
6346
+ this.aiFieldConfig = input();
6347
+ this.aiReadonly = input();
6348
+ this.aiPlugins = input();
6349
+ this.aiReferences = input.required();
6350
+ this.aiBuildRenderDataFn = input();
6351
+ this.aiGetI18nTextByKey = input();
6352
+ this.aiKeywords = input();
6353
+ this.AITableFieldType = AITableFieldType;
6354
+ this.AITableSelectOptionStyle = AITableSelectOptionStyle;
6355
+ this.isSelectedAll = computed(() => {
6356
+ return this.aiTable.selection().selectedRecords.size === this.aiRecords().length;
6357
+ });
6358
+ this.aiTableInitialized = output();
6359
+ this.aiAddRecord = output();
6360
+ this.aiAddField = output();
6361
+ this.aiMoveField = output();
6362
+ this.aiUpdateFieldValue = output();
6363
+ this.aiSetField = output();
6364
+ this.aiClick = output();
6365
+ this.aiDbClick = output();
6366
+ this.fieldMenus = computed(() => {
6367
+ const fieldMenusFn = this.aiFieldConfig()?.fieldMenus;
6368
+ if (fieldMenusFn && this.aiTable) {
6369
+ return fieldMenusFn(this.aiTable);
6370
+ }
6371
+ return [];
6372
+ });
6373
+ this.gridData = computed(() => {
6374
+ if (this.aiBuildRenderDataFn && this.aiBuildRenderDataFn() && this.aiTable) {
6375
+ return this.aiBuildRenderDataFn()(this.aiTable);
6421
6376
  }
6422
- if (element.tagName === 'polygon') {
6423
- d += ' Z';
6377
+ return {
6378
+ records: this.aiRecords(),
6379
+ fields: this.aiFields()
6380
+ };
6381
+ });
6382
+ this.ngZone = inject(NgZone);
6383
+ this.elementRef = inject(ElementRef);
6384
+ this.destroyRef = inject(DestroyRef);
6385
+ this.aiTableGridFieldService = inject(AITableGridFieldService);
6386
+ this.aiTableGridEventService = inject(AITableGridEventService);
6387
+ this.aiTableGridSelectionService = inject(AITableGridSelectionService);
6388
+ }
6389
+ ngOnInit() {
6390
+ this.initAITable();
6391
+ this.initService();
6392
+ }
6393
+ initAITable() {
6394
+ this.aiTable = createAITable(this.aiRecords, this.aiFields, this.gridData);
6395
+ if (this.aiGetI18nTextByKey()) {
6396
+ this.aiTable.getI18nTextByKey = this.aiGetI18nTextByKey();
6397
+ }
6398
+ this.aiPlugins()?.forEach((plugin) => {
6399
+ this.aiTable = plugin(this.aiTable);
6400
+ });
6401
+ this.aiTableInitialized.emit(this.aiTable);
6402
+ }
6403
+ initService() {
6404
+ this.aiTableGridEventService.initialize(this.aiTable, this.aiFieldConfig()?.fieldRenderers);
6405
+ this.aiTableGridSelectionService.initialize(this.aiTable);
6406
+ this.aiTableGridEventService.registerEvents(this.elementRef.nativeElement);
6407
+ this.aiTableGridFieldService.initAIFieldConfig(this.aiFieldConfig());
6408
+ AI_TABLE_GRID_FIELD_SERVICE_MAP.set(this.aiTable, this.aiTableGridFieldService);
6409
+ }
6410
+ addRecord() {
6411
+ const records = this.aiRecords();
6412
+ const recordCount = records.length;
6413
+ this.aiAddRecord.emit({
6414
+ originId: recordCount > 0 ? records[records.length - 1]._id : ''
6415
+ });
6416
+ }
6417
+ selectRecord(recordId) {
6418
+ this.aiTableGridSelectionService.selectRecord(recordId);
6419
+ }
6420
+ toggleSelectAll(checked) {
6421
+ this.aiTableGridSelectionService.toggleSelectAll(checked);
6422
+ }
6423
+ addField(gridColumnBlank, position) {
6424
+ const field = createDefaultField(this.aiTable, AITableFieldType.text);
6425
+ const popoverRef = this.aiTableGridFieldService.editFieldProperty(this.aiTable, {
6426
+ field,
6427
+ isUpdate: false,
6428
+ origin: gridColumnBlank,
6429
+ position
6430
+ });
6431
+ if (popoverRef && !this.aiFieldConfig()?.fieldSettingComponent) {
6432
+ popoverRef.componentInstance.addField.subscribe((defaultValue) => {
6433
+ const fields = this.gridData().fields;
6434
+ const fieldCount = fields.length;
6435
+ this.aiAddField.emit({
6436
+ originId: fieldCount > 0 ? fields[fields.length - 1]._id : '',
6437
+ defaultValue
6438
+ });
6439
+ });
6440
+ }
6441
+ }
6442
+ subscribeEvents() {
6443
+ this.ngZone.runOutsideAngular(() => {
6444
+ this.aiTableGridEventService.dblClickEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
6445
+ this.dblClick(event);
6446
+ });
6447
+ this.aiTableGridEventService.mousedownEvent$
6448
+ .pipe(mergeWith(this.aiTableGridEventService.globalMousedownEvent$), takeUntilDestroyed(this.destroyRef))
6449
+ .subscribe((event) => {
6450
+ this.aiTableGridSelectionService.updateSelect(event);
6451
+ });
6452
+ this.aiTableGridEventService.mouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
6453
+ this.mouseoverHandle(event);
6454
+ });
6455
+ this.aiTableGridEventService.globalMouseoverEvent$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
6456
+ this.closeHoverCellEditor(event);
6457
+ });
6458
+ });
6459
+ }
6460
+ dblClick(event) {
6461
+ const cellDom = event.target.closest('.grid-cell');
6462
+ const type = cellDom && cellDom.getAttribute('type');
6463
+ if (type && DBL_CLICK_EDIT_TYPE.includes(type)) {
6464
+ this.aiTableGridEventService.openEdit(cellDom);
6465
+ }
6466
+ }
6467
+ mouseoverHandle(event) {
6468
+ if (this.mouseoverRef) {
6469
+ this.mouseoverRef?.close();
6470
+ }
6471
+ const cellDom = event.target.closest('.grid-cell');
6472
+ const type = cellDom && cellDom.getAttribute('type');
6473
+ if (type && MOUSEOVER_EDIT_TYPE.includes(type)) {
6474
+ this.mouseoverRef = this.aiTableGridEventService.openEdit(cellDom);
6475
+ }
6476
+ }
6477
+ closeHoverCellEditor(e) {
6478
+ if (this.mouseoverRef) {
6479
+ const hasGrid = e.target && e.target.closest('.ai-table-grid');
6480
+ const hasCellEditor = e.target && e.target.closest('.grid-cell-editor');
6481
+ if (!hasGrid && !hasCellEditor) {
6482
+ this.mouseoverRef.close();
6424
6483
  }
6425
6484
  }
6426
- const fill = element.getAttribute('fill') || 'black';
6427
- const stroke = 'none';
6428
- const strokeWidth = element.getAttribute('stroke-width') || 0;
6429
- const opacity = parseFloat(element?.getAttribute('opacity') || '1');
6430
- const fillRule = element.getAttribute('fill-rule') || 'nonzero';
6431
- if (d) {
6432
- canvasObjects.push({
6433
- d,
6485
+ }
6486
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6487
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableGridBase, isStandalone: true, selector: "ai-table-grid-base", inputs: { aiRecords: { classPropertyName: "aiRecords", publicName: "aiRecords", isSignal: true, isRequired: true, transformFunction: null }, aiFields: { classPropertyName: "aiFields", publicName: "aiFields", isSignal: true, isRequired: true, transformFunction: null }, aiContextMenuItems: { classPropertyName: "aiContextMenuItems", publicName: "aiContextMenuItems", isSignal: true, isRequired: false, transformFunction: null }, aiFieldConfig: { classPropertyName: "aiFieldConfig", publicName: "aiFieldConfig", isSignal: true, isRequired: false, transformFunction: null }, aiReadonly: { classPropertyName: "aiReadonly", publicName: "aiReadonly", isSignal: true, isRequired: false, transformFunction: null }, aiPlugins: { classPropertyName: "aiPlugins", publicName: "aiPlugins", isSignal: true, isRequired: false, transformFunction: null }, aiReferences: { classPropertyName: "aiReferences", publicName: "aiReferences", isSignal: true, isRequired: true, transformFunction: null }, aiBuildRenderDataFn: { classPropertyName: "aiBuildRenderDataFn", publicName: "aiBuildRenderDataFn", isSignal: true, isRequired: false, transformFunction: null }, aiGetI18nTextByKey: { classPropertyName: "aiGetI18nTextByKey", publicName: "aiGetI18nTextByKey", isSignal: true, isRequired: false, transformFunction: null }, aiKeywords: { classPropertyName: "aiKeywords", publicName: "aiKeywords", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiRecords: "aiRecordsChange", aiFields: "aiFieldsChange", aiTableInitialized: "aiTableInitialized", aiAddRecord: "aiAddRecord", aiAddField: "aiAddField", aiMoveField: "aiMoveField", aiUpdateFieldValue: "aiUpdateFieldValue", aiSetField: "aiSetField", aiClick: "aiClick", aiDbClick: "aiDbClick" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6488
+ }
6489
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, decorators: [{
6490
+ type: Component,
6491
+ args: [{
6492
+ selector: 'ai-table-grid-base',
6493
+ template: '',
6494
+ standalone: true,
6495
+ changeDetection: ChangeDetectionStrategy.OnPush
6496
+ }]
6497
+ }] });
6498
+
6499
+ class AITableDomGrid extends AITableGridBase {
6500
+ ngOnInit() {
6501
+ super.ngOnInit();
6502
+ this.subscribeEvents();
6503
+ }
6504
+ openFieldMenu(e, field, fieldAction) {
6505
+ const moreBtn = e.target.closest('.grid-field-action');
6506
+ this.aiTableGridFieldService.openFieldMenu(this.aiTable, {
6507
+ origin: moreBtn,
6508
+ editOrigin: fieldAction,
6509
+ fieldId: field._id,
6510
+ fieldMenus: this.fieldMenus()
6511
+ });
6512
+ }
6513
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
6514
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableDomGrid, isStandalone: true, selector: "ai-table-dom-grid", host: { classAttribute: "ai-table-grid ai-table-dom-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], usesInheritance: true, ngImport: i0, template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SelectOptionPipe, name: "selectOption" }, { kind: "pipe", type: SelectOptionsPipe, name: "selectOptions" }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "ngmodule", type: ThyPopoverModule }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyRate, selector: "thy-rate", inputs: ["thyCount", "thyDisabled", "thyAllowHalf", "thyAllowClear", "thyTooltips", "thyIconTemplate"], outputs: ["thyItemHoverChange"] }, { kind: "component", type: ThyProgress, selector: "thy-progress", inputs: ["thyType", "thySize", "thyValue", "thyMax", "thyTips", "thyShape", "thyGapDegree", "thyGapPosition", "thyStrokeWidth"] }, { kind: "pipe", type: ThyDatePickerFormatPipe, name: "thyDatePickerFormat" }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyCheckboxModule }, { kind: "component", type: i3$1.ThyCheckbox, selector: "thy-checkbox,[thy-checkbox],[thyCheckbox]", inputs: ["thyIndeterminate"] }, { kind: "ngmodule", type: ThyAvatarModule }, { kind: "component", type: i4.ThyAvatar, selector: "thy-avatar", inputs: ["thyShowName", "thySrc", "thyName", "thySize", "thyShowRemove", "thyRemovable", "thyImgClass", "thyDisabled", "thyLoading", "thyFetchPriority"], outputs: ["thyOnRemove", "thyRemove", "thyError"] }, { kind: "component", type: i4.ThyAvatarList, selector: "thy-avatar-list", inputs: ["thyMode", "thyAvatarSize"] }, { kind: "pipe", type: IsSelectRecordPipe, name: "isSelectRecord" }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "pipe", type: UserPipe, name: "user" }, { kind: "pipe", type: SelectSettingPipe, name: "selectSetting" }, { kind: "pipe", type: MemberSettingPipe, name: "memberSetting" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6515
+ }
6516
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, decorators: [{
6517
+ type: Component,
6518
+ args: [{ selector: 'ai-table-dom-grid', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
6519
+ class: 'ai-table-grid ai-table-dom-grid'
6520
+ }, imports: [
6521
+ NgClass,
6522
+ NgComponentOutlet,
6523
+ CommonModule,
6524
+ FormsModule,
6525
+ SelectOptionPipe,
6526
+ SelectOptionsPipe,
6527
+ ThyTag,
6528
+ ThyPopoverModule,
6529
+ ThyIcon,
6530
+ ThyRate,
6531
+ ThyProgress,
6532
+ AITableFieldSetting,
6533
+ ThyDatePickerFormatPipe,
6534
+ ThyFlexibleText,
6535
+ ThyStopPropagationDirective,
6536
+ AITableFieldMenu,
6537
+ ThyAction,
6538
+ ThyDropdownDirective,
6539
+ ThyDropdownMenuComponent,
6540
+ ThyCheckboxModule,
6541
+ ProgressEditorComponent,
6542
+ ThyAvatarModule,
6543
+ NgTemplateOutlet,
6544
+ IsSelectRecordPipe,
6545
+ ProgressEditorComponent,
6546
+ SelectOptionComponent,
6547
+ UserPipe,
6548
+ SelectSettingPipe,
6549
+ MemberSettingPipe
6550
+ ], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n" }]
6551
+ }] });
6552
+
6553
+ class AITableIcon {
6554
+ constructor() {
6555
+ this.config = input.required();
6556
+ this.groupConfig = computed(() => {
6557
+ const { x, y, listening } = this.config();
6558
+ return { x, y, listening };
6559
+ });
6560
+ this.squareShapeConfig = computed(() => {
6561
+ const { name, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, strokeWidth = 1, background, cornerRadius, opacity } = this.config();
6562
+ return {
6563
+ name,
6564
+ width: backgroundWidth || size,
6565
+ height: backgroundHeight || size,
6566
+ strokeWidth: strokeWidth,
6567
+ fill: background || Colors.transparent,
6568
+ cornerRadius,
6569
+ opacity
6570
+ };
6571
+ });
6572
+ this.iconConfig = computed(() => {
6573
+ const { type, data, backgroundWidth, backgroundHeight, size = DEFAULT_ICON_SIZE, stroke, strokeWidth = 1, scaleX, scaleY, offsetX, offsetY, rotation, fill = Colors.gray600, transformsEnabled = 'position' } = this.config();
6574
+ let pathData = data;
6575
+ switch (type) {
6576
+ case AITableCheckType.checked:
6577
+ pathData = Check;
6578
+ break;
6579
+ case AITableCheckType.unchecked:
6580
+ pathData = Unchecked;
6581
+ break;
6582
+ }
6583
+ return {
6584
+ x: backgroundWidth && (backgroundWidth - size * (scaleX || 1)) / 2,
6585
+ y: backgroundHeight && (backgroundHeight - size * (scaleY || 1)) / 2,
6586
+ data: pathData,
6587
+ width: size,
6588
+ height: size,
6434
6589
  fill,
6590
+ offsetX,
6591
+ offsetY,
6592
+ scaleX,
6593
+ scaleY,
6594
+ rotation,
6435
6595
  stroke,
6436
6596
  strokeWidth,
6437
- opacity,
6438
- fillRule: fillRule
6439
- });
6440
- }
6441
- });
6442
- return canvasObjects;
6597
+ transformsEnabled,
6598
+ perfectDrawEnabled: false,
6599
+ listening: false
6600
+ };
6601
+ });
6602
+ }
6603
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6604
+ 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: `
6605
+ <ko-group [config]="groupConfig()">
6606
+ <ko-rect [config]="squareShapeConfig()"></ko-rect>
6607
+ <ko-path [config]="iconConfig()"></ko-path>
6608
+ </ko-group>
6609
+ `, 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 }); }
6443
6610
  }
6444
- const FileIcons = (() => {
6445
- const result = {};
6446
- Object.entries(fileIcons).forEach((fileIcon) => {
6447
- result[fileIcon[0]] = parseSVGToCanvasObjects(fileIcon[1]);
6448
- });
6449
- return result;
6450
- })();
6611
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableIcon, decorators: [{
6612
+ type: Component,
6613
+ args: [{
6614
+ selector: 'ai-table-icon',
6615
+ template: `
6616
+ <ko-group [config]="groupConfig()">
6617
+ <ko-rect [config]="squareShapeConfig()"></ko-rect>
6618
+ <ko-path [config]="iconConfig()"></ko-path>
6619
+ </ko-group>
6620
+ `,
6621
+ standalone: true,
6622
+ imports: [KoContainer, KoShape],
6623
+ changeDetection: ChangeDetectionStrategy.OnPush
6624
+ }]
6625
+ }] });
6451
6626
 
6452
- function getFileThumbnailName(ext) {
6453
- let result = 'defaultFile';
6454
- switch (ext) {
6455
- case 'doc':
6456
- case 'docx':
6457
- result = 'doc';
6458
- break;
6459
- case 'ppt':
6460
- case 'pptx':
6461
- result = 'ppt';
6462
- break;
6463
- case 'xls':
6464
- case 'xlsx':
6465
- result = 'xls';
6466
- break;
6467
- case 'css':
6468
- case 'scss':
6469
- case 'sass':
6470
- case 'less':
6471
- result = 'css';
6472
- break;
6473
- case 'png':
6474
- case 'jpeg':
6475
- case 'jpg':
6476
- case 'gif':
6477
- case 'bmp':
6478
- case 'svg':
6479
- result = 'img';
6480
- break;
6481
- case 'mp4':
6482
- case 'mkv':
6483
- case 'webm':
6484
- case 'mov':
6485
- case 'flv':
6486
- case '3gp':
6487
- case 'mpv':
6488
- case 'avi':
6489
- case 'mpeg':
6490
- case 'wmv':
6491
- result = 'video';
6492
- break;
6493
- case 'mp3':
6494
- case 'wma':
6495
- case 'wav':
6496
- case 'ape':
6497
- case 'flac':
6498
- case 'ogg':
6499
- case 'm4r':
6500
- case 'm4a':
6501
- result = 'mp3';
6502
- break;
6503
- case 'pdf':
6504
- case 'txt':
6505
- case 'apk':
6506
- case 'bak':
6507
- case 'cs':
6508
- case 'csv':
6509
- case 'exe':
6510
- case 'fla':
6511
- case 'html':
6512
- case 'ipa':
6513
- case 'java':
6514
- case 'js':
6515
- case 'php':
6516
- case 'rar':
6517
- case 'swf':
6518
- case 'ttf':
6519
- case 'vss':
6520
- case 'xsd':
6521
- case 'zip':
6522
- case 'youdaonote':
6523
- case 'evernote':
6524
- case 'yinxiang':
6525
- case 'quip':
6526
- case 'onenote':
6527
- case 'onedrive':
6528
- case 'box':
6529
- case 'shimo':
6530
- case 'processon':
6531
- result = ext;
6532
- break;
6533
- default:
6534
- result = 'defaultFile';
6535
- break;
6627
+ class AITableAddField {
6628
+ constructor() {
6629
+ this.config = input.required();
6630
+ this.btnWidth = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
6631
+ this.x = computed(() => {
6632
+ const lastColumnWidth = this.config().coordinate.getColumnWidth(this.config().columnStopIndex);
6633
+ const lastColumnOffset = this.config().coordinate.getColumnOffset(this.config().columnStopIndex);
6634
+ return lastColumnWidth + lastColumnOffset;
6635
+ });
6636
+ this.rectConfig = computed(() => {
6637
+ const { pointPosition: { targetName }, readonly } = this.config();
6638
+ const fill = targetName === AI_TABLE_FIELD_ADD_BUTTON ? Colors.gray80 : Colors.white;
6639
+ return {
6640
+ name: generateTargetName({
6641
+ targetName: AI_TABLE_FIELD_ADD_BUTTON,
6642
+ fieldId: this.config().fields[this.config().columnStopIndex]._id,
6643
+ mouseStyle: readonly ? 'default' : 'pointer'
6644
+ }),
6645
+ x: AI_TABLE_OFFSET,
6646
+ y: AI_TABLE_OFFSET,
6647
+ width: this.config().coordinate.containerWidth - this.x() < this.btnWidth
6648
+ ? this.btnWidth
6649
+ : this.config().coordinate.containerWidth - this.x(),
6650
+ height: this.config().coordinate.rowInitSize,
6651
+ stroke: Colors.gray200,
6652
+ strokeWidth: 1,
6653
+ listening: true,
6654
+ fill
6655
+ };
6656
+ });
6657
+ this.addIconConfig = computed(() => {
6658
+ const { readonly } = this.config();
6659
+ const offsetY = (this.config().coordinate.rowInitSize - AI_TABLE_ICON_COMMON_SIZE) / 2;
6660
+ return {
6661
+ x: AI_TABLE_CELL_PADDING,
6662
+ y: offsetY,
6663
+ data: AddOutlinedPath,
6664
+ fill: Colors.gray600,
6665
+ listening: false,
6666
+ visible: isNil(readonly) ? true : !readonly
6667
+ };
6668
+ });
6536
6669
  }
6537
- return result;
6670
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6671
+ 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: `
6672
+ <ko-group [config]="{ x: x() }">
6673
+ <ko-group>
6674
+ <ko-rect [config]="rectConfig()"></ko-rect>
6675
+ </ko-group>
6676
+ <ko-group>
6677
+ @if (addIconConfig().visible) {
6678
+ <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
6679
+ }
6680
+ </ko-group>
6681
+ </ko-group>
6682
+ `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableIcon, selector: "ai-table-icon", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6538
6683
  }
6539
- function getFileThumbnailSvgString(ext) {
6540
- let result = 'defaultFile';
6541
- switch (ext) {
6542
- case 'doc':
6543
- case 'docx':
6544
- result = doc;
6545
- break;
6546
- case 'ppt':
6547
- case 'pptx':
6548
- result = ppt;
6549
- break;
6550
- case 'xls':
6551
- case 'xlsx':
6552
- result = xls;
6553
- break;
6554
- case 'css':
6555
- case 'scss':
6556
- case 'sass':
6557
- case 'less':
6558
- result = css;
6559
- break;
6560
- case 'png':
6561
- case 'jpeg':
6562
- case 'jpg':
6563
- case 'gif':
6564
- case 'bmp':
6565
- case 'svg':
6566
- result = img;
6567
- break;
6568
- case 'mp4':
6569
- case 'mkv':
6570
- case 'webm':
6571
- case 'mov':
6572
- case 'flv':
6573
- case '3gp':
6574
- case 'mpv':
6575
- case 'avi':
6576
- case 'mpeg':
6577
- case 'wmv':
6578
- result = video;
6579
- break;
6580
- case 'mp3':
6581
- case 'wma':
6582
- case 'wav':
6583
- case 'ape':
6584
- case 'flac':
6585
- case 'ogg':
6586
- case 'm4r':
6587
- case 'm4a':
6588
- result = mp3;
6589
- break;
6590
- case 'pdf':
6591
- result = pdf;
6592
- break;
6593
- case 'txt':
6594
- result = txt;
6595
- break;
6596
- case 'apk':
6597
- result = apk;
6598
- break;
6599
- case 'bak':
6600
- result = apk;
6601
- break;
6602
- case 'cs':
6603
- result = cs;
6604
- break;
6605
- case 'csv':
6606
- result = csv;
6607
- break;
6608
- case 'exe':
6609
- result = exe;
6610
- break;
6611
- case 'fla':
6612
- result = fla;
6613
- break;
6614
- case 'html':
6615
- result = html;
6616
- break;
6617
- case 'ipa':
6618
- result = ipa;
6619
- break;
6620
- case 'java':
6621
- result = java;
6622
- break;
6623
- case 'js':
6624
- result = js;
6625
- break;
6626
- case 'php':
6627
- result = php;
6628
- break;
6629
- case 'rar':
6630
- result = rar;
6631
- break;
6632
- case 'swf':
6633
- result = swf;
6634
- break;
6635
- case 'ttf':
6636
- result = ttf;
6637
- break;
6638
- case 'vss':
6639
- result = vss;
6640
- break;
6641
- case 'xsd':
6642
- result = xsd;
6643
- break;
6644
- case 'zip':
6645
- result = zip;
6646
- break;
6647
- default:
6648
- result = defaultFile;
6649
- break;
6684
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableAddField, decorators: [{
6685
+ type: Component,
6686
+ args: [{
6687
+ selector: 'ai-table-add-field',
6688
+ template: `
6689
+ <ko-group [config]="{ x: x() }">
6690
+ <ko-group>
6691
+ <ko-rect [config]="rectConfig()"></ko-rect>
6692
+ </ko-group>
6693
+ <ko-group>
6694
+ @if (addIconConfig().visible) {
6695
+ <ai-table-icon [config]="addIconConfig()"></ai-table-icon>
6696
+ }
6697
+ </ko-group>
6698
+ </ko-group>
6699
+ `,
6700
+ standalone: true,
6701
+ imports: [KoContainer, KoShape, AITableIcon],
6702
+ changeDetection: ChangeDetectionStrategy.OnPush
6703
+ }]
6704
+ }] });
6705
+
6706
+ /**
6707
+ * 用于处理表格行或单元格的布局和绘制。
6708
+ * 它提供了基本的布局信息(如位置、大小等),并定义了常用的绘图方法(如渲染缩进区域、添加新字段的空白区域等)。
6709
+ * 该类继承自 Drawer,并被其他更具体的布局类(如 RecordRowLayout)扩展和使用
6710
+ */
6711
+ class Layout extends Drawer {
6712
+ constructor() {
6713
+ super(...arguments);
6714
+ // 定义当前单元格或行的位置
6715
+ this.x = 0;
6716
+ this.y = 0;
6717
+ // 行高
6718
+ this.rowHeight = 0;
6719
+ // 列宽
6720
+ this.columnWidth = 0;
6721
+ // 行索引
6722
+ this.rowIndex = 0;
6723
+ // 列索引
6724
+ this.columnIndex = 0;
6725
+ // 列数
6726
+ this.columnCount = 0;
6727
+ this.containerWidth = 0;
6728
+ }
6729
+ // 用于初始化或重置布局的基本属性。这个方法通常在每次渲染新的一行或单元格时调用,确保布局信息是最新的
6730
+ init({ x, y, rowIndex, columnIndex, rowHeight, columnWidth, columnCount, containerWidth }) {
6731
+ this.x = x;
6732
+ this.y = y;
6733
+ this.rowIndex = rowIndex;
6734
+ this.columnIndex = columnIndex;
6735
+ this.rowHeight = rowHeight;
6736
+ this.columnWidth = columnWidth;
6737
+ this.columnCount = columnCount;
6738
+ this.containerWidth = containerWidth;
6739
+ }
6740
+ // 当前单元格是否是行的第一列
6741
+ get isFirst() {
6742
+ return this.columnIndex === 0;
6743
+ }
6744
+ // 当前单元格是否是行的最后一列
6745
+ get isLast() {
6746
+ return this.columnIndex === this.columnCount - 1;
6747
+ }
6748
+ renderAddFieldBlank({ isHoverRow, isCheckedRow }) {
6749
+ const rowHeight = this.rowHeight;
6750
+ const fill = isCheckedRow ? this.colors.itemActiveBgColor : isHoverRow ? this.colors.gray80 : this.colors.transparent;
6751
+ const addFieldBlankX = this.x + this.columnWidth + AI_TABLE_OFFSET;
6752
+ this.rect({
6753
+ x: addFieldBlankX,
6754
+ y: this.y + AI_TABLE_OFFSET,
6755
+ width: this.containerWidth - addFieldBlankX < AI_TABLE_FIELD_ADD_BUTTON_WIDTH
6756
+ ? AI_TABLE_FIELD_ADD_BUTTON_WIDTH
6757
+ : this.containerWidth - addFieldBlankX,
6758
+ height: rowHeight,
6759
+ fill
6760
+ });
6650
6761
  }
6651
- return result;
6652
6762
  }
6653
- function getFileCanvasPaths(ext) {
6654
- const fileThumbnailName = getFileThumbnailName(ext);
6655
- return FileIcons[fileThumbnailName];
6763
+
6764
+ class AddRowLayout extends Layout {
6765
+ renderAddFieldBlank({ isHoverRow, isCheckedRow }) {
6766
+ super.renderAddFieldBlank({ isHoverRow, isCheckedRow });
6767
+ const rowHeight = this.rowHeight;
6768
+ const defaultWidth = AI_TABLE_FIELD_ADD_BUTTON_WIDTH;
6769
+ const width = this.containerWidth - this.x < defaultWidth ? defaultWidth : this.containerWidth - this.x;
6770
+ this.line({
6771
+ x: this.x + this.columnWidth,
6772
+ y: this.y,
6773
+ points: [0, rowHeight, width, rowHeight],
6774
+ stroke: this.colors.gray200
6775
+ });
6776
+ }
6777
+ renderCell({ width, isHoverRow }) {
6778
+ const x = this.x;
6779
+ const y = this.y;
6780
+ const rowHeight = this.rowHeight;
6781
+ const fill = isHoverRow ? this.colors.gray80 : this.colors.transparent;
6782
+ this.rect({
6783
+ x,
6784
+ y: y + AI_TABLE_OFFSET,
6785
+ width: width,
6786
+ height: rowHeight,
6787
+ fill
6788
+ });
6789
+ this.line({
6790
+ x,
6791
+ y: y + rowHeight,
6792
+ points: [0, 0, width, 0],
6793
+ stroke: this.colors.gray200
6794
+ });
6795
+ }
6796
+ renderFirstCell({ isHoverRow }) {
6797
+ if (!this.isFirst)
6798
+ return;
6799
+ const y = this.y;
6800
+ const rowHeight = this.rowHeight;
6801
+ const columnWidth = this.columnWidth;
6802
+ const frozenOffset = AI_TABLE_OFFSET;
6803
+ const fill = isHoverRow ? this.colors.gray80 : this.colors.transparent;
6804
+ this.rect({
6805
+ x: frozenOffset,
6806
+ y: y + AI_TABLE_OFFSET,
6807
+ width: columnWidth + AI_TABLE_ROW_HEAD_WIDTH - frozenOffset + 1,
6808
+ height: rowHeight,
6809
+ fill
6810
+ });
6811
+ this.line({
6812
+ x: frozenOffset,
6813
+ y,
6814
+ points: [0, rowHeight, columnWidth + AI_TABLE_ROW_HEAD_WIDTH - frozenOffset + 1, rowHeight],
6815
+ stroke: this.colors.gray200
6816
+ });
6817
+ this.path({
6818
+ x: AI_TABLE_CELL_PADDING,
6819
+ y: y + (rowHeight - AI_TABLE_ICON_COMMON_SIZE) / 2 - AI_TABLE_OFFSET,
6820
+ data: AddOutlinedPath,
6821
+ size: AI_TABLE_ROW_HEAD_SIZE,
6822
+ fill: this.colors.gray600
6823
+ });
6824
+ }
6825
+ renderLastCell({ isHoverRow, isCheckedRow }) {
6826
+ if (!this.isLast)
6827
+ return;
6828
+ const width = this.columnWidth;
6829
+ if (!this.isFirst) {
6830
+ this.renderCell({
6831
+ width,
6832
+ isHoverRow
6833
+ });
6834
+ }
6835
+ this.renderAddFieldBlank({ isHoverRow, isCheckedRow });
6836
+ }
6837
+ renderCommonCell({ isHoverRow }) {
6838
+ if (this.isFirst || this.isLast)
6839
+ return;
6840
+ this.renderCell({
6841
+ width: this.columnWidth,
6842
+ isHoverRow
6843
+ });
6844
+ }
6845
+ render({ isHoverRow, isCheckedRow }) {
6846
+ this.renderFirstCell({
6847
+ isHoverRow
6848
+ });
6849
+ this.renderCommonCell({
6850
+ isHoverRow
6851
+ });
6852
+ this.renderLastCell({
6853
+ isHoverRow,
6854
+ isCheckedRow
6855
+ });
6856
+ }
6656
6857
  }
6858
+ const addRowLayout = new AddRowLayout();
6657
6859
 
6658
6860
  /**
6659
6861
  * 处理和渲染表格单元格的内容
@@ -7265,15 +7467,12 @@ class CellDrawer extends Drawer {
7265
7467
  }
7266
7468
  renderCellAttachment(render, ctx) {
7267
7469
  const { references, x, y, field, transformValue: _cellValue, rowHeight, columnWidth, isActive } = render;
7268
- const cellValue = _cellValue;
7269
- if (!cellValue?.length || !references) {
7270
- return;
7271
- }
7470
+ const cellValue = _cellValue || [];
7272
7471
  const fileIconSize = AI_TABLE_FILE_ICON_SIZE;
7273
7472
  const itemHeight = AI_TABLE_FILE_ICON_ITEM_HEIGHT;
7274
7473
  const isOperating = isActive;
7275
7474
  let currentX = AI_TABLE_CELL_PADDING;
7276
- let currentY = (AI_TABLE_ROW_BLANK_HEIGHT - fileIconSize) / 2;
7475
+ let currentY = (AI_TABLE_ROW_BLANK_HEIGHT - itemHeight) / 2;
7277
7476
  const itemOtherWidth = fileIconSize + AI_TABLE_FIELD_ITEM_MARGIN_RIGHT;
7278
7477
  const maxHeight = isActive ? 130 - AI_TABLE_CELL_MULTI_PADDING_TOP : rowHeight - AI_TABLE_CELL_MULTI_PADDING_TOP;
7279
7478
  const maxTextWidth = isOperating
@@ -7282,7 +7481,7 @@ class CellDrawer extends Drawer {
7282
7481
  const listCount = cellValue.length;
7283
7482
  let isOverflow = false;
7284
7483
  for (let index = 0; index < listCount; index++) {
7285
- const attachmentInfo = references.attachments[cellValue[index]];
7484
+ const attachmentInfo = references?.attachments[cellValue[index]];
7286
7485
  if (!attachmentInfo)
7287
7486
  continue;
7288
7487
  const { title, addition } = attachmentInfo;
@@ -7890,7 +8089,8 @@ const createColumnHeads = (config) => {
7890
8089
  };
7891
8090
  };
7892
8091
  const fieldHeads = [];
7893
- const fieldMenus = config.aiTable.context?.aiFieldConfig()?.fieldMenus || [];
8092
+ const fieldMenuFn = config.aiTable.context?.aiFieldConfig()?.fieldMenus;
8093
+ const fieldMenus = (fieldMenuFn && fieldMenuFn(aiTable)) || [];
7894
8094
  let noMoreIcon = false;
7895
8095
  if (fieldMenus.length === 0) {
7896
8096
  noMoreIcon = true;
@@ -8332,7 +8532,6 @@ const createActiveCellBorder = (config) => {
8332
8532
  columnIndex,
8333
8533
  columnCount: totalColumnCount
8334
8534
  });
8335
- // active 外边界和非 active 外边界 box 大小保持一致
8336
8535
  const currentConfig = {
8337
8536
  x: x + offset + AI_TABLE_OFFSET,
8338
8537
  y: y + AI_TABLE_OFFSET,
@@ -8369,7 +8568,7 @@ class AITableHoverCells {
8369
8568
  };
8370
8569
  });
8371
8570
  this.hoverCellConfig = computed(() => {
8372
- const { aiTable, coordinate } = this.config();
8571
+ const { aiTable, coordinate, references, readonly } = this.config();
8373
8572
  const pointPosition = aiTable.context.pointPosition();
8374
8573
  const hoverCell = this.hoverCell();
8375
8574
  if (!hoverCell) {
@@ -8377,10 +8576,7 @@ class AITableHoverCells {
8377
8576
  }
8378
8577
  const { field, recordId, fieldId, renderComponentDefinition } = hoverCell;
8379
8578
  const cellValue = AITableQueries.getFieldValue(aiTable, [recordId, field._id]);
8380
- const transformValue = transformCellValue(aiTable, field, cellValue) || {};
8381
- if (Object.keys(transformValue).length === 0) {
8382
- return;
8383
- }
8579
+ const transformValue = transformCellValue(aiTable, field, cellValue);
8384
8580
  const { rowHeight, columnCount, rowCount } = coordinate;
8385
8581
  const columnIndex = pointPosition.columnIndex;
8386
8582
  const rowIndex = pointPosition.rowIndex;
@@ -8402,10 +8598,12 @@ class AITableHoverCells {
8402
8598
  const renderY = 0 - AI_TABLE_OFFSET * 2;
8403
8599
  const result = {
8404
8600
  field,
8601
+ recordId,
8405
8602
  aiTable,
8406
8603
  coordinate,
8407
8604
  x,
8408
8605
  y,
8606
+ readonly,
8409
8607
  render: {
8410
8608
  aiTable,
8411
8609
  recordId,
@@ -8417,7 +8615,8 @@ class AITableHoverCells {
8417
8615
  rowHeight,
8418
8616
  cellValue,
8419
8617
  transformValue,
8420
- style
8618
+ style,
8619
+ references
8421
8620
  }
8422
8621
  };
8423
8622
  return result;
@@ -8637,22 +8836,17 @@ class AITableDragComponent {
8637
8836
  this.draggedData = null;
8638
8837
  this.mouseStartPosition = null;
8639
8838
  this.aiTableDrag = null;
8640
- effect(() => {
8641
- const drag = this.aiTableGridSelectionService.aiTable.dragState?.();
8642
- if (drag && drag.sourceIds.size > 0) {
8643
- if (!this.rect || !this.line) {
8644
- return;
8645
- }
8646
- this.aiTableDrag = drag;
8647
- }
8648
- else {
8649
- this.aiTableDrag = null;
8650
- }
8651
- });
8839
+ effect(() => this.handleDragStateChange());
8652
8840
  }
8653
8841
  ngOnInit() {
8842
+ this.initElements();
8843
+ this.setupEventListeners();
8844
+ }
8845
+ initElements() {
8654
8846
  this.rect = this.elementRef.nativeElement.querySelector('.rect');
8655
- this.line = this.elementRef.nativeElement.querySelector('.line');
8847
+ this.auxiliaryLine = this.elementRef.nativeElement.querySelector('.auxiliary-line');
8848
+ }
8849
+ setupEventListeners() {
8656
8850
  this.mousedownListener = this.render2.listen('window', 'mousedown', (e) => {
8657
8851
  this.mouseStartPosition = { x: e.x, y: e.y };
8658
8852
  });
@@ -8661,7 +8855,7 @@ class AITableDragComponent {
8661
8855
  cancelAnimationFrame(this.timer);
8662
8856
  }
8663
8857
  this.timer = requestAnimationFrame(() => {
8664
- if (this.mouseStartPosition && this.aiTableDrag) {
8858
+ if (this.aiTableDrag && this.mouseStartPosition) {
8665
8859
  this.handleDrag(e, this.aiTableDrag);
8666
8860
  }
8667
8861
  });
@@ -8672,72 +8866,23 @@ class AITableDragComponent {
8672
8866
  this.handleDragEnd();
8673
8867
  });
8674
8868
  }
8675
- handleDrag(e, drag) {
8676
- if (drag.type !== DragType.none) {
8677
- this.render2.setStyle(this.elementRef.nativeElement, 'display', 'block');
8869
+ handleDragStateChange() {
8870
+ const drag = this.aiTableGridSelectionService.aiTable.dragState?.();
8871
+ if (!drag || drag.type === DragType.none || !this.rect || !this.auxiliaryLine) {
8872
+ this.aiTableDrag = null;
8873
+ return;
8678
8874
  }
8679
- else {
8875
+ this.aiTableDrag = drag;
8876
+ }
8877
+ handleDrag(e, drag) {
8878
+ if (drag.type === DragType.none) {
8680
8879
  return;
8681
8880
  }
8682
- const moveX = e.x - this.mouseStartPosition.x;
8683
- const aiTable = this.aiTableGridSelectionService.aiTable;
8684
- const scroll = drag.scroll || { x: 0, y: 0 };
8685
- const coordinate = drag.coordinate;
8881
+ this.setDisplayStyle('block');
8882
+ const moveX = e.x - (this.mouseStartPosition?.x || 0);
8686
8883
  switch (drag.type) {
8687
8884
  case DragType.field:
8688
- const fields = aiTable.gridData().fields;
8689
- let width = 0;
8690
- fields.forEach((field, index) => {
8691
- if (drag.sourceIds.has(field._id)) {
8692
- width += coordinate.columnIndicesSizeMap[index] || 0;
8693
- }
8694
- });
8695
- const visibleColumnIndexMap = aiTable.context.visibleColumnsIndexMap();
8696
- const sourceColumnIndex = visibleColumnIndexMap.get(drag.sourceIds.values().next().value) || 0;
8697
- const sourceColumnStartX = coordinate.getColumnOffset(sourceColumnIndex);
8698
- const sourceColumnWidth = coordinate.getColumnWidth(sourceColumnIndex);
8699
- // TODO: 目前默认第一列为冻结列,后期支持设置冻结列需要处理
8700
- const isSourceColumnFrozen = sourceColumnIndex === 0;
8701
- const pointerX = moveX + sourceColumnStartX;
8702
- // 拖拽中心点
8703
- const dragCenter = sourceColumnWidth / 2;
8704
- let targetColumnIndex = coordinate.getColumnStartIndex(pointerX + (isSourceColumnFrozen ? scroll.x : 0) + dragCenter);
8705
- let targetColumnStartX = coordinate.getColumnOffset(targetColumnIndex);
8706
- this.render2.setStyle(this.rect, 'cursor', 'move');
8707
- this.render2.setStyle(this.rect, 'width', `${width}px`);
8708
- this.render2.setStyle(this.rect, 'height', `100%`);
8709
- this.render2.setStyle(this.rect, 'top', 0);
8710
- this.render2.setStyle(this.rect, 'left', `${pointerX - (isSourceColumnFrozen ? 0 : scroll.x)}px`);
8711
- const lastColumnOffset = coordinate.getColumnOffset(coordinate.columnCount - 1);
8712
- const lastColumnWidth = coordinate.getColumnWidth(coordinate.columnCount - 1);
8713
- let isLastColumn = false;
8714
- // 处理最后一列
8715
- if (pointerX + dragCenter > lastColumnOffset + lastColumnWidth) {
8716
- targetColumnIndex = coordinate.columnCount;
8717
- targetColumnStartX = lastColumnOffset + lastColumnWidth;
8718
- isLastColumn = true;
8719
- }
8720
- if ((targetColumnIndex >= 0 && (targetColumnIndex - sourceColumnIndex > 1 || targetColumnIndex - sourceColumnIndex < 0)) ||
8721
- isLastColumn) {
8722
- this.render2.setStyle(this.line, 'width', `2px`);
8723
- this.render2.setStyle(this.line, 'height', `100%`);
8724
- this.render2.setStyle(this.line, 'top', 0);
8725
- this.render2.setStyle(this.line, 'left', `${targetColumnStartX - scroll.x}px`);
8726
- const fieldsIndex = [];
8727
- drag.sourceIds.forEach((id) => {
8728
- const index = visibleColumnIndexMap.get(id) || 0;
8729
- fieldsIndex.push(index);
8730
- });
8731
- // 向右移动目标在目标列的前一列
8732
- if (targetColumnIndex > sourceColumnIndex) {
8733
- targetColumnIndex -= 1;
8734
- }
8735
- this.draggedData = { type: DragType.field, targetIndex: targetColumnIndex, fieldIds: drag.sourceIds, fieldsIndex };
8736
- }
8737
- else {
8738
- this.render2.setStyle(this.line, 'width', 0);
8739
- this.draggedData = null;
8740
- }
8885
+ this.movingColumn(drag, moveX);
8741
8886
  break;
8742
8887
  case DragType.record:
8743
8888
  break;
@@ -8745,13 +8890,95 @@ class AITableDragComponent {
8745
8890
  break;
8746
8891
  }
8747
8892
  }
8893
+ movingColumn(drag, moveX) {
8894
+ const aiTable = this.aiTableGridSelectionService.aiTable;
8895
+ const scroll = drag.scroll || { x: 0, y: 0 };
8896
+ const coordinate = drag.coordinate;
8897
+ const fields = aiTable.gridData().fields;
8898
+ const width = this.calculateDragWidth(fields, coordinate, drag);
8899
+ const visibleColumnIndexMap = aiTable.context.visibleColumnsIndexMap();
8900
+ const sourceColumnIndex = visibleColumnIndexMap.get(drag.sourceIds.values().next().value) || 0;
8901
+ const sourceColumnStartX = coordinate.getColumnOffset(sourceColumnIndex);
8902
+ const sourceColumnWidth = coordinate.getColumnWidth(sourceColumnIndex);
8903
+ // TODO: 目前默认第一列为冻结列,后期支持设置冻结列需要处理
8904
+ const isSourceColumnFrozen = sourceColumnIndex === 0;
8905
+ const pointerX = moveX + sourceColumnStartX;
8906
+ // 拖拽中心点
8907
+ const dragCenter = sourceColumnWidth / 2;
8908
+ this.setRectStyles({
8909
+ cursor: 'move',
8910
+ width: `${width}px`,
8911
+ height: '100%',
8912
+ top: '0',
8913
+ left: `${pointerX - (isSourceColumnFrozen ? 0 : scroll.x)}px`
8914
+ });
8915
+ const lastColumnOffset = coordinate.getColumnOffset(coordinate.columnCount - 1);
8916
+ const lastColumnWidth = coordinate.getColumnWidth(coordinate.columnCount - 1);
8917
+ let targetColumnIndex = coordinate.getColumnStartIndex(pointerX + (isSourceColumnFrozen ? scroll.x : 0) + dragCenter);
8918
+ let targetColumnStartX = coordinate.getColumnOffset(targetColumnIndex);
8919
+ let isLastColumn = false;
8920
+ // 处理最后一列
8921
+ if (pointerX + dragCenter > lastColumnOffset + lastColumnWidth) {
8922
+ targetColumnIndex = coordinate.columnCount;
8923
+ targetColumnStartX = lastColumnOffset + lastColumnWidth;
8924
+ isLastColumn = true;
8925
+ }
8926
+ if ((targetColumnIndex >= 0 && (targetColumnIndex - sourceColumnIndex > 1 || targetColumnIndex - sourceColumnIndex < 0)) ||
8927
+ isLastColumn) {
8928
+ this.setAuxiliaryLineStyles({
8929
+ width: '2px',
8930
+ height: '100%',
8931
+ top: 0,
8932
+ left: `${targetColumnStartX - scroll.x}px`
8933
+ });
8934
+ const fieldsIndex = [];
8935
+ drag.sourceIds.forEach((id) => {
8936
+ const index = visibleColumnIndexMap.get(id) || 0;
8937
+ fieldsIndex.push(index);
8938
+ });
8939
+ // 向右移动目标在目标列的前一列
8940
+ if (targetColumnIndex > sourceColumnIndex) {
8941
+ targetColumnIndex -= 1;
8942
+ }
8943
+ this.draggedData = { type: DragType.field, targetIndex: targetColumnIndex, fieldIds: drag.sourceIds, fieldsIndex };
8944
+ }
8945
+ else {
8946
+ this.resetAuxiliaryLine();
8947
+ this.draggedData = null;
8948
+ }
8949
+ }
8748
8950
  handleDragEnd() {
8749
- this.render2.setStyle(this.elementRef.nativeElement, 'display', 'none');
8951
+ this.setDisplayStyle('none');
8750
8952
  if (this.draggedData) {
8751
8953
  this.dragEnd.emit({ ...this.draggedData });
8752
8954
  this.draggedData = null;
8753
8955
  }
8754
8956
  }
8957
+ calculateDragWidth(fields, coordinate, drag) {
8958
+ let width = 0;
8959
+ fields.forEach((field, index) => {
8960
+ if (drag.sourceIds.has(field._id)) {
8961
+ width += coordinate.columnIndicesSizeMap[index] || 0;
8962
+ }
8963
+ });
8964
+ return width;
8965
+ }
8966
+ setDisplayStyle(display) {
8967
+ this.render2.setStyle(this.elementRef.nativeElement, 'display', display);
8968
+ }
8969
+ setRectStyles(styles) {
8970
+ Object.entries(styles).forEach(([prop, value]) => {
8971
+ this.render2.setStyle(this.rect, prop, value);
8972
+ });
8973
+ }
8974
+ setAuxiliaryLineStyles(styles) {
8975
+ Object.entries(styles).forEach(([prop, value]) => {
8976
+ this.render2.setStyle(this.auxiliaryLine, prop, value);
8977
+ });
8978
+ }
8979
+ resetAuxiliaryLine() {
8980
+ this.setAuxiliaryLineStyles({ width: 0 });
8981
+ }
8755
8982
  ngOnDestroy() {
8756
8983
  if (this.mousedownListener)
8757
8984
  this.mousedownListener();
@@ -8765,13 +8992,13 @@ class AITableDragComponent {
8765
8992
  }
8766
8993
  }
8767
8994
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDragComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8768
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AITableDragComponent, isStandalone: true, selector: "ai-table-drag", outputs: { dragEnd: "dragEnd" }, host: { classAttribute: "drag-container" }, ngImport: i0, template: "<div class=\"rect\"></div>\n<div class=\"line\"></div>", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8995
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AITableDragComponent, isStandalone: true, selector: "ai-table-drag", outputs: { dragEnd: "dragEnd" }, host: { classAttribute: "drag-container" }, ngImport: i0, template: "<div class=\"rect\"></div>\n<div class=\"auxiliary-line\"></div>", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8769
8996
  }
8770
8997
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDragComponent, decorators: [{
8771
8998
  type: Component,
8772
8999
  args: [{ selector: 'ai-table-drag', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
8773
9000
  class: 'drag-container'
8774
- }, template: "<div class=\"rect\"></div>\n<div class=\"line\"></div>" }]
9001
+ }, template: "<div class=\"rect\"></div>\n<div class=\"auxiliary-line\"></div>" }]
8775
9002
  }], ctorParameters: () => [] });
8776
9003
 
8777
9004
  class AITableGrid extends AITableGridBase {
@@ -8813,7 +9040,7 @@ class AITableGrid extends AITableGridBase {
8813
9040
  rowInitSize: AI_TABLE_FIELD_HEAD_HEIGHT,
8814
9041
  columnInitSize: AI_TABLE_ROW_HEAD_WIDTH,
8815
9042
  rowIndicesSizeMap: {},
8816
- columnIndicesSizeMap: getColumnIndicesSizeMap(fields),
9043
+ columnIndicesSizeMap: getColumnIndicesSizeMap(this.aiTable, fields),
8817
9044
  frozenColumnCount: this.frozenColumnCount()
8818
9045
  });
8819
9046
  return {
@@ -8955,7 +9182,7 @@ class AITableGrid extends AITableGridBase {
8955
9182
  return;
8956
9183
  const { context } = this.aiTable;
8957
9184
  const { x, y } = pos;
8958
- const curMousePosition = getMousePosition(x, y, this.coordinate(), AITable.getVisibleFields(this.aiTable), context, targetName);
9185
+ const curMousePosition = getMousePosition(this.aiTable, x, y, this.coordinate(), AITable.getVisibleFields(this.aiTable), context, targetName);
8959
9186
  handleMouseStyle(curMousePosition.realTargetName, curMousePosition.areaType, this.containerElement());
8960
9187
  context.setPointPosition(curMousePosition);
8961
9188
  this.timer = null;
@@ -9023,7 +9250,10 @@ class AITableGrid extends AITableGridBase {
9023
9250
  x: mouseEvent.x,
9024
9251
  y: mouseEvent.y
9025
9252
  };
9026
- const menuItems = this.aiContextMenuItems();
9253
+ const menuItems = [];
9254
+ if (this.aiContextMenuItems()) {
9255
+ menuItems.push(...this.aiContextMenuItems()(this.aiTable));
9256
+ }
9027
9257
  if (!menuItems.length || menuItems.every((item) => !!(item.hidden && item.hidden(this.aiTable, targetName, position)))) {
9028
9258
  return;
9029
9259
  }
@@ -9047,17 +9277,17 @@ class AITableGrid extends AITableGridBase {
9047
9277
  case AI_TABLE_ROW_ADD_BUTTON: {
9048
9278
  this.aiTableGridSelectionService.clearSelection();
9049
9279
  this.addRecord();
9050
- return;
9280
+ break;
9051
9281
  }
9052
9282
  case AI_TABLE_ROW_SELECT_CHECKBOX: {
9053
9283
  const pointRecordId = context.linearRows()[pointRowIndex]?._id;
9054
9284
  this.selectRecord(pointRecordId);
9055
- return;
9285
+ break;
9056
9286
  }
9057
9287
  case AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX: {
9058
9288
  const isChecked = this.aiTable.selection().selectAllState === AITableSelectAllState.all;
9059
9289
  this.toggleSelectAll(!isChecked);
9060
- return;
9290
+ break;
9061
9291
  }
9062
9292
  case AI_TABLE_FIELD_ADD_BUTTON: {
9063
9293
  this.aiTableGridSelectionService.clearSelection();
@@ -9067,7 +9297,7 @@ class AITableGrid extends AITableGridBase {
9067
9297
  x: fieldGroupRect.x + containerRect.x,
9068
9298
  y: containerRect.y + fieldGroupRect.y + fieldGroupRect.height
9069
9299
  });
9070
- return;
9300
+ break;
9071
9301
  }
9072
9302
  case AI_TABLE_FIELD_HEAD_MORE:
9073
9303
  mouseEvent.preventDefault();
@@ -9095,36 +9325,52 @@ class AITableGrid extends AITableGridBase {
9095
9325
  editFieldPosition
9096
9326
  });
9097
9327
  }
9098
- return;
9328
+ break;
9099
9329
  }
9330
+ const targetNameDetail = getDetailByTargetName(e.event.target.name());
9331
+ this.aiClick.emit({
9332
+ ...e,
9333
+ targetNameDetail
9334
+ });
9335
+ return;
9100
9336
  }
9101
9337
  stageDblclick(e) {
9338
+ const _targetName = e.event.target.name();
9339
+ const targetNameDetail = getDetailByTargetName(_targetName);
9102
9340
  if (this.aiReadonly()) {
9341
+ this.aiDbClick.emit({
9342
+ ...e,
9343
+ targetNameDetail
9344
+ });
9103
9345
  return;
9104
9346
  }
9105
- const _targetName = e.event.target.name();
9106
- const { fieldId, recordId } = getDetailByTargetName(_targetName);
9347
+ const { fieldId, recordId } = targetNameDetail;
9107
9348
  if (!recordId || !fieldId) {
9108
9349
  return;
9109
9350
  }
9110
9351
  const field = this.aiTable.fieldsMap()[fieldId];
9111
9352
  const fieldType = field.type;
9112
- if (!DBL_CLICK_EDIT_TYPE.includes(fieldType)) {
9113
- return;
9353
+ if (DBL_CLICK_EDIT_TYPE.includes(fieldType)) {
9354
+ setTimeout(() => {
9355
+ this.aiTableGridEventService.openCellEditor(this.aiTable, {
9356
+ viewContainerRef: this.viewContainerRef,
9357
+ container: this.containerElement(),
9358
+ coordinate: this.coordinate(),
9359
+ fieldId: fieldId,
9360
+ recordId: recordId,
9361
+ references: this.aiReferences(),
9362
+ updateFieldValue: (value) => {
9363
+ this.aiUpdateFieldValue.emit(value);
9364
+ }
9365
+ });
9366
+ }, 0);
9114
9367
  }
9115
- setTimeout(() => {
9116
- this.aiTableGridEventService.openCellEditor(this.aiTable, {
9117
- viewContainerRef: this.viewContainerRef,
9118
- container: this.containerElement(),
9119
- coordinate: this.coordinate(),
9120
- fieldId: fieldId,
9121
- recordId: recordId,
9122
- references: this.aiReferences(),
9123
- updateFieldValue: (value) => {
9124
- this.aiUpdateFieldValue.emit(value);
9125
- }
9368
+ else {
9369
+ this.aiDbClick.emit({
9370
+ ...e,
9371
+ targetNameDetail
9126
9372
  });
9127
- }, 0);
9373
+ }
9128
9374
  }
9129
9375
  bindWheel() {
9130
9376
  fromEvent(this.containerElement(), 'wheel', { passive: false })
@@ -9236,18 +9482,24 @@ class AITableGrid extends AITableGridBase {
9236
9482
  fromEvent(document, 'keydown')
9237
9483
  .pipe(filter((event) => (event.ctrlKey || event.metaKey) && (event.key === 'c' || event.key === 'v')), takeUntilDestroyed(this.destroyRef))
9238
9484
  .subscribe(async (event) => {
9485
+ const hasSelectedCells = this.aiTable.selection().selectedCells.size > 0;
9486
+ if (!hasSelectedCells) {
9487
+ return;
9488
+ }
9489
+ const hasEditingCell = !!this.aiTableGridEventService.getCurrentEditCell();
9239
9490
  if (event.key === 'c') {
9240
9491
  const clipboardData = buildClipboardData(this.aiTable);
9241
9492
  if (clipboardData) {
9242
9493
  writeToClipboard(clipboardData).then(() => {
9243
9494
  const copiedCellsCount = this.aiTable.selection().selectedCells.size;
9244
- this.notifyService.success(`已复制 ${copiedCellsCount} 个单元格`, undefined, {
9495
+ const message = getI18nTextByKey(this.aiTable, AITableGridI18nKey.copiedCells).replace('{count}', copiedCellsCount.toString());
9496
+ this.notifyService.success(message, undefined, {
9245
9497
  placement: 'bottomLeft'
9246
9498
  });
9247
9499
  });
9248
9500
  }
9249
9501
  }
9250
- else if (event.key === 'v') {
9502
+ else if (event.key === 'v' && !hasEditingCell) {
9251
9503
  event.preventDefault();
9252
9504
  const actions = {
9253
9505
  updateFieldValue: (data) => {
@@ -9265,7 +9517,7 @@ class AITableGrid extends AITableGridBase {
9265
9517
  };
9266
9518
  writeToAITable(this.aiTable, actions).then((isPasteSuccess) => {
9267
9519
  if (!isPasteSuccess) {
9268
- this.notifyService.error('粘贴内容不符合当前类型', undefined, {
9520
+ this.notifyService.error(getI18nTextByKey(this.aiTable, AITableGridI18nKey.invalidPasteContent), undefined, {
9269
9521
  placement: 'bottomLeft'
9270
9522
  });
9271
9523
  }
@@ -9323,5 +9575,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
9323
9575
  * Generated bundle index. Do not edit.
9324
9576
  */
9325
9577
 
9326
- export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsSameOptionPipe, AITableFieldSetting, AITableFieldType, AITableFilterOperation, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridSelectionService, AITableMemberType, AITableMouseDownType, AITableQueries, AITableRenderer, AITableRowColumnType, AITableRowType, AITableSelectAllState, AITableSelectOptionStyle, AITableStatType, AI_TABLE_ACTION_COMMON_SIZE, AI_TABLE_BLANK, AI_TABLE_CELL, AI_TABLE_CELL_ACTIVE_BORDER_WIDTH, AI_TABLE_CELL_ADD_ITEM_BUTTON_SIZE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, AI_TABLE_CELL_FIELD_ITEM_HEIGHT, AI_TABLE_CELL_MAX_ROW_COUNT, AI_TABLE_CELL_MEMBER_ITEM_HEIGHT, AI_TABLE_CELL_MEMBER_ITEM_PADDING, AI_TABLE_CELL_MEMBER_MAX_HEIGHT, AI_TABLE_CELL_MULTI_DOT_RADIUS, AI_TABLE_CELL_MULTI_ITEM_MARGIN_LEFT, AI_TABLE_CELL_MULTI_ITEM_MARGIN_TOP, AI_TABLE_CELL_MULTI_ITEM_MIN_WIDTH, AI_TABLE_CELL_MULTI_PADDING_LEFT, AI_TABLE_CELL_MULTI_PADDING_TOP, AI_TABLE_CELL_PADDING, AI_TABLE_COMMON_FONT_SIZE, AI_TABLE_DEFAULT_COLUMN_WIDTH, AI_TABLE_DOT_RADIUS, AI_TABLE_FIELD_ADD_BUTTON, AI_TABLE_FIELD_ADD_BUTTON_WIDTH, AI_TABLE_FIELD_HEAD, AI_TABLE_FIELD_HEAD_HEIGHT, AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE, AI_TABLE_FIELD_HEAD_MORE, AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX, AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH, AI_TABLE_FIELD_ITEM_MARGIN_RIGHT, AI_TABLE_FIELD_MAX_WIDTH, AI_TABLE_FIELD_MIDDLE_WIDTH, AI_TABLE_FIELD_MINI_WIDTH, AI_TABLE_FIELD_MIN_WIDTH, AI_TABLE_FILE_ICON_ITEM_HEIGHT, AI_TABLE_FILE_ICON_SIZE, AI_TABLE_GRID_FIELD_SERVICE_MAP, AI_TABLE_ICON_COMMON_SIZE, AI_TABLE_MEMBER_AVATAR_SIZE, AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT, AI_TABLE_MEMBER_ITEM_PADDING_RIGHT, AI_TABLE_MIN_TEXT_WIDTH, AI_TABLE_OFFSET, AI_TABLE_OPTION_ITEM_FONT_SIZE, AI_TABLE_OPTION_ITEM_HEIGHT, AI_TABLE_OPTION_ITEM_PADDING, AI_TABLE_OPTION_ITEM_RADIUS, AI_TABLE_PIECE_RADIUS, AI_TABLE_PIECE_WIDTH, AI_TABLE_POPOVER_LEFT_OFFSET, AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS, AI_TABLE_PROGRESS_BAR_HEIGHT, AI_TABLE_PROGRESS_BAR_RADIUS, AI_TABLE_PROGRESS_TEXT_Width, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_HEIGHT, AI_TABLE_ROW_SELECT_CHECKBOX, AI_TABLE_SCROLL_BAR_PADDING, AI_TABLE_TAG_FONT_SIZE, AI_TABLE_TAG_PADDING, AI_TABLE_TEXT_GAP, AbstractEditCellEditor, AddOutlinedPath, AttachmentPath, Check, Colors, ColumnCalendarFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnSelectFilledPath, ColumnTextFilledPath, Coordinate, DBL_CLICK_EDIT_TYPE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_STYLE, DEFAULT_FONT_WEIGHT, DEFAULT_ICON_SHAPE, DEFAULT_ICON_SIZE, DEFAULT_POINT_POSITION, DEFAULT_SCROLL_STATE, DEFAULT_TEXT_ALIGN_CENTER, DEFAULT_TEXT_ALIGN_LEFT, DEFAULT_TEXT_ALIGN_RIGHT, DEFAULT_TEXT_DECORATION, DEFAULT_TEXT_ELLIPSIS, DEFAULT_TEXT_FILL, DEFAULT_TEXT_LINE_HEIGHT, DEFAULT_TEXT_LISTENING, DEFAULT_TEXT_MAX_CACHE, DEFAULT_TEXT_MAX_HEIGHT, DEFAULT_TEXT_SCALE, DEFAULT_TEXT_TRANSFORMS_ENABLED, DEFAULT_TEXT_VERTICAL_ALIGN_MIDDLE, DEFAULT_TEXT_VERTICAL_ALIGN_TOP, DEFAULT_TEXT_WRAP, DEFAULT_WRAP_TEXT_MAX_ROW, DateCellEditorComponent, DepartmentOutlinedPath, Direction, DragType, FONT_SIZE_SM, FieldModelMap, FieldOptions, GRID_CELL_EDITOR_MAP, IsSelectRecordPipe, LinkCellEditorComponent, MIN_COLUMN_WIDTH, MOUSEOVER_EDIT_TYPE, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, ProgressEditorComponent, RatingCellEditorComponent, RendererContext, RowHeight, SelectCellEditorComponent, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextMeasure, Unchecked, UserPipe, WebOutlinedPath, aiTableFragmentAttribute, buildClipboardData, buildGridData, buildGridLinearRows, castToString, compareNumber, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, extractLinkHref, extractText, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getDefaultFieldValue, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getFieldValue, getHoverCell, getHoverEditorBoxOffset, getHoverEditorSpace, getMousePosition, getPlaceHolderCellsConfigs, getSystemFieldValue, getTargetName, getTextWidth, getVisibleRangeInfo, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isArrayField, isCellMatchKeywords, isClipboardReadSupported, isClipboardReadTextSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isEmpty, isMac, isNumberFiled, isSameFieldOption, isSelectedField, isSystemField, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, readFromClipboard, scrollMax, setMouseStyle, shortIdCreator, shortIdsCreator, stringInclude, textDataCache, transformCellValue, writeToAITable, writeToClipboard, zhIntlCollator };
9578
+ export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsSameOptionPipe, AITableFieldSetting, AITableFieldType, AITableFilterOperation, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridI18nKey, AITableGridSelectionService, AITableMemberType, AITableMouseDownType, AITableQueries, AITableRenderer, AITableRowColumnType, AITableRowType, AITableSelectAllState, AITableSelectOptionStyle, AITableStatType, AI_TABLE_ACTION_COMMON_RADIUS, AI_TABLE_ACTION_COMMON_RIGHT_PADDING, AI_TABLE_ACTION_COMMON_SIZE, AI_TABLE_BLANK, AI_TABLE_CELL, AI_TABLE_CELL_ACTIVE_BORDER_WIDTH, AI_TABLE_CELL_ADD_ITEM_BUTTON_SIZE, AI_TABLE_CELL_ATTACHMENT_ADD, AI_TABLE_CELL_ATTACHMENT_FILE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, AI_TABLE_CELL_FIELD_ITEM_HEIGHT, AI_TABLE_CELL_MAX_ROW_COUNT, AI_TABLE_CELL_MEMBER_ITEM_HEIGHT, AI_TABLE_CELL_MEMBER_ITEM_PADDING, AI_TABLE_CELL_MEMBER_MAX_HEIGHT, AI_TABLE_CELL_MULTI_DOT_RADIUS, AI_TABLE_CELL_MULTI_ITEM_MARGIN_LEFT, AI_TABLE_CELL_MULTI_ITEM_MARGIN_TOP, AI_TABLE_CELL_MULTI_ITEM_MIN_WIDTH, AI_TABLE_CELL_MULTI_PADDING_LEFT, AI_TABLE_CELL_MULTI_PADDING_TOP, AI_TABLE_CELL_PADDING, AI_TABLE_COMMON_FONT_SIZE, AI_TABLE_DEFAULT_COLUMN_WIDTH, AI_TABLE_DOT_RADIUS, AI_TABLE_FIELD_ADD_BUTTON, AI_TABLE_FIELD_ADD_BUTTON_WIDTH, AI_TABLE_FIELD_HEAD, AI_TABLE_FIELD_HEAD_HEIGHT, AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE, AI_TABLE_FIELD_HEAD_MORE, AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX, AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH, AI_TABLE_FIELD_ITEM_MARGIN_RIGHT, AI_TABLE_FIELD_MAX_WIDTH, AI_TABLE_FIELD_MIDDLE_WIDTH, AI_TABLE_FIELD_MINI_WIDTH, AI_TABLE_FIELD_MIN_WIDTH, AI_TABLE_FILE_ICON_ITEM_HEIGHT, AI_TABLE_FILE_ICON_SIZE, AI_TABLE_GRID_FIELD_SERVICE_MAP, AI_TABLE_ICON_COMMON_SIZE, AI_TABLE_MEMBER_AVATAR_SIZE, AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT, AI_TABLE_MEMBER_ITEM_PADDING_RIGHT, AI_TABLE_MIN_TEXT_WIDTH, AI_TABLE_OFFSET, AI_TABLE_OPTION_ITEM_FONT_SIZE, AI_TABLE_OPTION_ITEM_HEIGHT, AI_TABLE_OPTION_ITEM_PADDING, AI_TABLE_OPTION_ITEM_RADIUS, AI_TABLE_PIECE_RADIUS, AI_TABLE_PIECE_WIDTH, AI_TABLE_POPOVER_LEFT_OFFSET, AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS, AI_TABLE_PROGRESS_BAR_HEIGHT, AI_TABLE_PROGRESS_BAR_RADIUS, AI_TABLE_PROGRESS_TEXT_Width, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_HEIGHT, AI_TABLE_ROW_SELECT_CHECKBOX, AI_TABLE_SCROLL_BAR_PADDING, AI_TABLE_TAG_FONT_SIZE, AI_TABLE_TAG_PADDING, AI_TABLE_TEXT_GAP, AbstractEditCellEditor, AddOutlinedPath, AttachmentPath, Check, Colors, ColumnCalendarFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnSelectFilledPath, ColumnTextFilledPath, Coordinate, DBL_CLICK_EDIT_TYPE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_STYLE, DEFAULT_FONT_WEIGHT, DEFAULT_ICON_SHAPE, DEFAULT_ICON_SIZE, DEFAULT_POINT_POSITION, DEFAULT_SCROLL_STATE, DEFAULT_TEXT_ALIGN_CENTER, DEFAULT_TEXT_ALIGN_LEFT, DEFAULT_TEXT_ALIGN_RIGHT, DEFAULT_TEXT_DECORATION, DEFAULT_TEXT_ELLIPSIS, DEFAULT_TEXT_FILL, DEFAULT_TEXT_LINE_HEIGHT, DEFAULT_TEXT_LISTENING, DEFAULT_TEXT_MAX_CACHE, DEFAULT_TEXT_MAX_HEIGHT, DEFAULT_TEXT_SCALE, DEFAULT_TEXT_TRANSFORMS_ENABLED, DEFAULT_TEXT_VERTICAL_ALIGN_MIDDLE, DEFAULT_TEXT_VERTICAL_ALIGN_TOP, DEFAULT_TEXT_WRAP, DEFAULT_WRAP_TEXT_MAX_ROW, DateCellEditorComponent, DepartmentOutlinedPath, Direction, DragType, FONT_SIZE_SM, FieldModelMap, GRID_CELL_EDITOR_MAP, IsSelectRecordPipe, LinkCellEditorComponent, MIN_COLUMN_WIDTH, MOUSEOVER_EDIT_TYPE, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, ProgressEditorComponent, RatingCellEditorComponent, RendererContext, RowHeight, SelectCellEditorComponent, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextMeasure, Unchecked, UserPipe, WebOutlinedPath, aiTableFragmentAttribute, buildClipboardData, buildGridData, buildGridLinearRows, castToString, compareNumber, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, extractLinkHref, extractText, generateNewName, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getDefaultFieldValue, getDefaultI18nTextByKey, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getFieldOptions, getFieldValue, getHoverCell, getHoverEditorBoxOffset, getHoverEditorSpace, getI18nTextByKey, getMousePosition, getPlaceHolderCellsConfigs, getSystemFieldValue, getTargetName, getTextWidth, getVisibleRangeInfo, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isArrayField, isCellMatchKeywords, isClipboardReadSupported, isClipboardReadTextSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isEmpty, isMac, isNumberFiled, isSameFieldOption, isSelectedField, isSystemField, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, readFromClipboard, scrollMax, setMouseStyle, shortIdCreator, shortIdsCreator, stringInclude, textDataCache, transformCellValue, writeToAITable, writeToClipboard, zhIntlCollator };
9327
9579
  //# sourceMappingURL=ai-table-grid.mjs.map