@ai-table/grid 0.0.44 → 0.0.46

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 (86) hide show
  1. package/components/cell-editors/date/date-editor.component.d.ts +1 -0
  2. package/components/cell-editors/date/date-editor.component.d.ts.map +1 -1
  3. package/components/cell-editors/link/edit-link/edit-link.component.d.ts +13 -3
  4. package/components/cell-editors/link/edit-link/edit-link.component.d.ts.map +1 -1
  5. package/components/cell-editors/link/link-editor.component.d.ts +1 -0
  6. package/components/cell-editors/link/link-editor.component.d.ts.map +1 -1
  7. package/components/drag/drag.component.d.ts +15 -1
  8. package/components/drag/drag.component.d.ts.map +1 -1
  9. package/components/drag/drag.component.scss +1 -1
  10. package/components/field-setting/field-setting.component.d.ts +17 -3
  11. package/components/field-setting/field-setting.component.d.ts.map +1 -1
  12. package/constants/table.d.ts +1 -0
  13. package/constants/table.d.ts.map +1 -1
  14. package/core/constants/field.d.ts +2 -2
  15. package/core/constants/field.d.ts.map +1 -1
  16. package/core/types/ai-table.d.ts +2 -0
  17. package/core/types/ai-table.d.ts.map +1 -1
  18. package/core/types/core.d.ts +11 -6
  19. package/core/types/core.d.ts.map +1 -1
  20. package/core/utils/common.d.ts +1 -0
  21. package/core/utils/common.d.ts.map +1 -1
  22. package/core/utils/field.d.ts +1 -1
  23. package/core/utils/field.d.ts.map +1 -1
  24. package/core/utils/{shoft-id.d.ts → short-id.d.ts} +1 -1
  25. package/core/utils/{shoft-id.d.ts.map → short-id.d.ts.map} +1 -1
  26. package/esm2022/components/cell-editors/date/date-editor.component.mjs +9 -3
  27. package/esm2022/components/cell-editors/link/edit-link/edit-link.component.mjs +27 -12
  28. package/esm2022/components/cell-editors/link/link-editor.component.mjs +12 -8
  29. package/esm2022/components/drag/drag.component.mjs +178 -79
  30. package/esm2022/components/field-setting/field-setting.component.mjs +30 -15
  31. package/esm2022/constants/table.mjs +2 -1
  32. package/esm2022/core/constants/field.mjs +95 -95
  33. package/esm2022/core/types/ai-table.mjs +1 -1
  34. package/esm2022/core/types/core.mjs +1 -2
  35. package/esm2022/core/utils/common.mjs +13 -1
  36. package/esm2022/core/utils/field.mjs +13 -8
  37. package/esm2022/core/utils/id-creator.mjs +2 -2
  38. package/esm2022/core/utils/queries.mjs +2 -2
  39. package/esm2022/core/utils/{shoft-id.mjs → short-id.mjs} +1 -1
  40. package/esm2022/dom-grid.component.mjs +3 -3
  41. package/esm2022/grid-base.component.mjs +16 -5
  42. package/esm2022/grid.component.mjs +40 -9
  43. package/esm2022/renderer/components/cells/link.component.mjs +2 -2
  44. package/esm2022/renderer/components/field-head.component.mjs +18 -2
  45. package/esm2022/renderer/creations/create-active-cell-border.mjs +1 -2
  46. package/esm2022/renderer/creations/create-heads.mjs +3 -2
  47. package/esm2022/services/selection.service.mjs +4 -1
  48. package/esm2022/types/grid.mjs +1 -1
  49. package/esm2022/utils/build.mjs +6 -6
  50. package/esm2022/utils/cell.mjs +4 -3
  51. package/esm2022/utils/clipboard/paste.mjs +4 -9
  52. package/esm2022/utils/field/model/select.mjs +31 -9
  53. package/esm2022/utils/i18n.mjs +85 -0
  54. package/esm2022/utils/index.mjs +2 -1
  55. package/esm2022/utils/position.mjs +3 -3
  56. package/esm2022/utils/visible-range.mjs +3 -3
  57. package/fesm2022/ai-table-grid.mjs +596 -283
  58. package/fesm2022/ai-table-grid.mjs.map +1 -1
  59. package/grid-base.component.d.ts +8 -4
  60. package/grid-base.component.d.ts.map +1 -1
  61. package/grid.component.d.ts.map +1 -1
  62. package/package.json +1 -1
  63. package/renderer/components/field-head.component.d.ts +8 -0
  64. package/renderer/components/field-head.component.d.ts.map +1 -1
  65. package/renderer/creations/create-active-cell-border.d.ts.map +1 -1
  66. package/renderer/creations/create-heads.d.ts.map +1 -1
  67. package/services/selection.service.d.ts +2 -1
  68. package/services/selection.service.d.ts.map +1 -1
  69. package/types/grid.d.ts +2 -1
  70. package/types/grid.d.ts.map +1 -1
  71. package/utils/build.d.ts +2 -2
  72. package/utils/build.d.ts.map +1 -1
  73. package/utils/cell.d.ts +1 -1
  74. package/utils/cell.d.ts.map +1 -1
  75. package/utils/clipboard/paste.d.ts +2 -2
  76. package/utils/clipboard/paste.d.ts.map +1 -1
  77. package/utils/field/model/select.d.ts +1 -1
  78. package/utils/field/model/select.d.ts.map +1 -1
  79. package/utils/i18n.d.ts +39 -0
  80. package/utils/i18n.d.ts.map +1 -0
  81. package/utils/index.d.ts +1 -0
  82. package/utils/index.d.ts.map +1 -1
  83. package/utils/position.d.ts +2 -2
  84. package/utils/position.d.ts.map +1 -1
  85. package/utils/visible-range.d.ts +2 -2
  86. package/utils/visible-range.d.ts.map +1 -1
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, computed, output, inject, ElementRef, Component, ChangeDetectionStrategy, Input, EventEmitter, Output, ChangeDetectorRef, ViewChild, HostListener, 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';
@@ -44,6 +44,7 @@ import { ThyProgress } from 'ngx-tethys/progress';
44
44
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
45
45
  import { LRUCache } from 'lru-cache';
46
46
  import { fromUnixTime, subDays } from 'date-fns';
47
+ import { DEFAULT_COLORS } from 'ngx-tethys/color-picker';
47
48
  import Konva from 'konva';
48
49
  import { Shape } from 'konva/lib/Shape';
49
50
  import { Sprite } from 'konva/lib/shapes/Sprite';
@@ -152,7 +153,6 @@ var AITableFieldType;
152
153
  AITableFieldType["number"] = "number";
153
154
  AITableFieldType["date"] = "date";
154
155
  AITableFieldType["member"] = "member";
155
- // cascadeSelect = 'cascade_select', // 包含单选和多选,参数复杂后续再进行设计
156
156
  AITableFieldType["progress"] = "progress";
157
157
  AITableFieldType["rate"] = "rate";
158
158
  AITableFieldType["link"] = "link";
@@ -203,105 +203,189 @@ var DragType;
203
203
  DragType["none"] = "none";
204
204
  })(DragType || (DragType = {}));
205
205
 
206
+ var AITableGridI18nKey;
207
+ (function (AITableGridI18nKey) {
208
+ AITableGridI18nKey["dataPickerPlaceholder"] = "dataPickerPlaceholder";
209
+ AITableGridI18nKey["linkTooltip"] = "linkTooltip";
210
+ AITableGridI18nKey["invalidLinkFormat"] = "invalidLinkFormat";
211
+ AITableGridI18nKey["linkRequired"] = "linkRequired";
212
+ AITableGridI18nKey["linkText"] = "linkText";
213
+ AITableGridI18nKey["linkUrl"] = "linkUrl";
214
+ AITableGridI18nKey["inputText"] = "inputText";
215
+ AITableGridI18nKey["inputUrl"] = "inputUrl";
216
+ AITableGridI18nKey["fieldColumnName"] = "fieldColumnName";
217
+ AITableGridI18nKey["fieldColumnNamePlaceholder"] = "fieldColumnNamePlaceholder";
218
+ AITableGridI18nKey["fieldType"] = "fieldType";
219
+ AITableGridI18nKey["allowMultipleMembers"] = "allowMultipleMembers";
220
+ AITableGridI18nKey["cancel"] = "cancel";
221
+ AITableGridI18nKey["apply"] = "apply";
222
+ AITableGridI18nKey["fieldNameRequired"] = "fieldNameRequired";
223
+ AITableGridI18nKey["fieldNameDuplicate"] = "fieldNameDuplicate";
224
+ AITableGridI18nKey["confirm"] = "confirm";
225
+ AITableGridI18nKey["copiedCells"] = "copiedCells";
226
+ AITableGridI18nKey["invalidPasteContent"] = "invalidPasteContent";
227
+ AITableGridI18nKey["fieldTypeText"] = "fieldTypeText";
228
+ AITableGridI18nKey["fieldTypeSelect"] = "fieldTypeSelect";
229
+ AITableGridI18nKey["fieldTypeMultiSelect"] = "fieldTypeMultiSelect";
230
+ AITableGridI18nKey["fieldTypeNumber"] = "fieldTypeNumber";
231
+ AITableGridI18nKey["fieldTypeDate"] = "fieldTypeDate";
232
+ AITableGridI18nKey["fieldTypeMember"] = "fieldTypeMember";
233
+ AITableGridI18nKey["fieldTypeProgress"] = "fieldTypeProgress";
234
+ AITableGridI18nKey["fieldTypeRate"] = "fieldTypeRate";
235
+ AITableGridI18nKey["fieldTypeLink"] = "fieldTypeLink";
236
+ AITableGridI18nKey["fieldTypeAttachment"] = "fieldTypeAttachment";
237
+ AITableGridI18nKey["fieldTypeCreatedBy"] = "fieldTypeCreatedBy";
238
+ AITableGridI18nKey["fieldTypeCreatedAt"] = "fieldTypeCreatedAt";
239
+ AITableGridI18nKey["fieldTypeUpdatedBy"] = "fieldTypeUpdatedBy";
240
+ AITableGridI18nKey["fieldTypeUpdatedAt"] = "fieldTypeUpdatedAt";
241
+ })(AITableGridI18nKey || (AITableGridI18nKey = {}));
242
+ const AITableI18nText = {
243
+ [AITableGridI18nKey.dataPickerPlaceholder]: '选择日期',
244
+ [AITableGridI18nKey.linkTooltip]: '链接',
245
+ [AITableGridI18nKey.invalidLinkFormat]: '链接格式不正确',
246
+ [AITableGridI18nKey.linkRequired]: '链接不能为空',
247
+ [AITableGridI18nKey.linkText]: '文本',
248
+ [AITableGridI18nKey.linkUrl]: '链接',
249
+ [AITableGridI18nKey.inputText]: '输入文本',
250
+ [AITableGridI18nKey.inputUrl]: '输入链接',
251
+ [AITableGridI18nKey.fieldColumnName]: '表格列名',
252
+ [AITableGridI18nKey.fieldColumnNamePlaceholder]: '输入列名称',
253
+ [AITableGridI18nKey.fieldType]: '列类型',
254
+ [AITableGridI18nKey.allowMultipleMembers]: '允许选择多个成员',
255
+ [AITableGridI18nKey.cancel]: '取消',
256
+ [AITableGridI18nKey.apply]: '应用',
257
+ [AITableGridI18nKey.fieldNameRequired]: '列名不能为空',
258
+ [AITableGridI18nKey.fieldNameDuplicate]: '列名已存在',
259
+ [AITableGridI18nKey.confirm]: '确定',
260
+ [AITableGridI18nKey.copiedCells]: '已复制 {count} 个单元格',
261
+ [AITableGridI18nKey.invalidPasteContent]: '粘贴内容不符合当前类型', // 新增
262
+ [AITableGridI18nKey.fieldTypeText]: '单行文本',
263
+ [AITableGridI18nKey.fieldTypeSelect]: '单选',
264
+ [AITableGridI18nKey.fieldTypeMultiSelect]: '多选',
265
+ [AITableGridI18nKey.fieldTypeNumber]: '数字',
266
+ [AITableGridI18nKey.fieldTypeDate]: '日期',
267
+ [AITableGridI18nKey.fieldTypeMember]: '成员',
268
+ [AITableGridI18nKey.fieldTypeProgress]: '进度',
269
+ [AITableGridI18nKey.fieldTypeRate]: '评分',
270
+ [AITableGridI18nKey.fieldTypeLink]: '链接',
271
+ [AITableGridI18nKey.fieldTypeAttachment]: '附件',
272
+ [AITableGridI18nKey.fieldTypeCreatedBy]: '创建人',
273
+ [AITableGridI18nKey.fieldTypeCreatedAt]: '创建时间',
274
+ [AITableGridI18nKey.fieldTypeUpdatedBy]: '更新人',
275
+ [AITableGridI18nKey.fieldTypeUpdatedAt]: '更新时间'
276
+ };
277
+ const getDefaultI18nTextByKey = (key) => {
278
+ return AITableI18nText[key] || key;
279
+ };
280
+ const getI18nTextByKey = (aiTable, key) => {
281
+ if (aiTable.getI18nTextByKey) {
282
+ const customText = aiTable.getI18nTextByKey(key);
283
+ if (customText) {
284
+ return customText;
285
+ }
286
+ }
287
+ const defaultText = getDefaultI18nTextByKey(key);
288
+ return defaultText;
289
+ };
290
+
206
291
  const AI_TABLE_FIELD_MINI_WIDTH = 140;
207
292
  const AI_TABLE_FIELD_MIN_WIDTH = 160;
208
293
  const AI_TABLE_FIELD_MIDDLE_WIDTH = 200;
209
294
  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
- ];
295
+ function getFieldOptions(aiTable) {
296
+ return [
297
+ {
298
+ type: AITableFieldType.text,
299
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeText),
300
+ icon: 'font',
301
+ width: AI_TABLE_FIELD_MAX_WIDTH
302
+ },
303
+ {
304
+ type: AITableFieldType.select,
305
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeSelect),
306
+ icon: 'check-circle',
307
+ width: AI_TABLE_FIELD_MIN_WIDTH
308
+ },
309
+ {
310
+ type: AITableFieldType.select,
311
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeMultiSelect),
312
+ icon: 'list-check',
313
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH,
314
+ settings: {
315
+ is_multiple: true
316
+ }
317
+ },
318
+ {
319
+ type: AITableFieldType.number,
320
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeNumber),
321
+ icon: 'hashtag',
322
+ width: AI_TABLE_FIELD_MINI_WIDTH
323
+ },
324
+ {
325
+ type: AITableFieldType.date,
326
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeDate),
327
+ icon: 'calendar',
328
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH
329
+ },
330
+ {
331
+ type: AITableFieldType.member,
332
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeMember),
333
+ icon: 'user',
334
+ width: AI_TABLE_FIELD_MIN_WIDTH,
335
+ settings: {
336
+ is_multiple: false
337
+ }
338
+ },
339
+ {
340
+ type: AITableFieldType.progress,
341
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeProgress),
342
+ icon: 'progress',
343
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH
344
+ },
345
+ {
346
+ type: AITableFieldType.rate,
347
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeRate),
348
+ icon: 'star-circle',
349
+ width: AI_TABLE_FIELD_MIN_WIDTH
350
+ },
351
+ {
352
+ type: AITableFieldType.link,
353
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeLink),
354
+ icon: 'link-insert',
355
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH
356
+ },
357
+ {
358
+ type: AITableFieldType.attachment,
359
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeAttachment),
360
+ icon: 'attachment',
361
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH
362
+ },
363
+ {
364
+ type: AITableFieldType.createdBy,
365
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeCreatedBy),
366
+ icon: 'user',
367
+ width: AI_TABLE_FIELD_MIN_WIDTH
368
+ },
369
+ {
370
+ type: AITableFieldType.createdAt,
371
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeCreatedAt),
372
+ icon: 'calendar',
373
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH
374
+ },
375
+ {
376
+ type: AITableFieldType.updatedBy,
377
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeUpdatedBy),
378
+ icon: 'user',
379
+ width: AI_TABLE_FIELD_MIN_WIDTH
380
+ },
381
+ {
382
+ type: AITableFieldType.updatedAt,
383
+ name: getI18nTextByKey(aiTable, AITableGridI18nKey.fieldTypeUpdatedAt),
384
+ icon: 'calendar',
385
+ width: AI_TABLE_FIELD_MIDDLE_WIDTH
386
+ }
387
+ ];
388
+ }
305
389
 
306
390
  var AITableAvatarSize;
307
391
  (function (AITableAvatarSize) {
@@ -674,6 +758,49 @@ function shortIdsCreator(count) {
674
758
  return shortId(undefined, 8, count);
675
759
  }
676
760
 
761
+ function createAITable(records, fields, gridData) {
762
+ const aiTable = {
763
+ records,
764
+ fields,
765
+ gridData,
766
+ selection: signal({
767
+ selectedRecords: new Set(),
768
+ selectedFields: new Set(),
769
+ selectedCells: new Set(),
770
+ activeCell: null,
771
+ selectAllState: AITableSelectAllState.none
772
+ }),
773
+ keywordsMatchedCells: signal(new Set()),
774
+ recordsMap: computed(() => {
775
+ return records().reduce((object, item) => {
776
+ object[item._id] = item;
777
+ return object;
778
+ }, {});
779
+ }),
780
+ fieldsMap: computed(() => {
781
+ return fields().reduce((object, item) => {
782
+ object[item._id] = item;
783
+ return object;
784
+ }, {});
785
+ }),
786
+ recordsWillHidden: signal([]),
787
+ recordsWillMove: signal([])
788
+ };
789
+ return aiTable;
790
+ }
791
+ function generateNewName(existNames, count, name) {
792
+ let newName = name;
793
+ let suffix = count;
794
+ if (count > 1) {
795
+ newName = `${name} ${suffix}`;
796
+ }
797
+ while (existNames.includes(newName)) {
798
+ suffix++;
799
+ newName = `${name} ${suffix}`;
800
+ }
801
+ return newName;
802
+ }
803
+
677
804
  const isArrayField = (field) => {
678
805
  return [
679
806
  AITableFieldType.member,
@@ -699,17 +826,20 @@ function getDefaultFieldValue(field) {
699
826
  return '';
700
827
  }
701
828
  function createDefaultFieldName(aiTable, field) {
702
- const fieldOption = getFieldOptionByField(field);
829
+ const fieldOption = getFieldOptionByField(aiTable, field);
703
830
  if (fieldOption) {
831
+ const allNames = aiTable.fields().map((item) => item.name);
704
832
  const count = aiTable.fields().filter((item) => {
705
833
  return isSameFieldOption(field, item);
706
834
  }).length;
707
- return count === 0 ? fieldOption.name : fieldOption.name + ' ' + count;
835
+ return generateNewName(allNames, count, fieldOption.name);
708
836
  }
709
- return FieldOptions[0].name;
837
+ const fieldOptions = getFieldOptions(aiTable);
838
+ return fieldOptions[0].name;
710
839
  }
711
- function getFieldOptionByField(field) {
712
- let fieldOption = FieldOptions.find((item) => isSameFieldOption(item, field));
840
+ function getFieldOptionByField(aiTable, field) {
841
+ const fieldOptions = getFieldOptions(aiTable);
842
+ let fieldOption = fieldOptions.find((item) => isSameFieldOption(item, field));
713
843
  if (fieldOption && field.type === AITableFieldType.member && field.settings?.is_multiple) {
714
844
  fieldOption.width = AI_TABLE_FIELD_MIDDLE_WIDTH;
715
845
  }
@@ -722,41 +852,11 @@ function isSameFieldOption(fieldOption, field) {
722
852
  : true));
723
853
  }
724
854
  function createDefaultField(aiTable, type = AITableFieldType.text) {
725
- const fieldOption = FieldOptions.find((item) => item.type === type);
855
+ const fieldOptions = getFieldOptions(aiTable);
856
+ const fieldOption = fieldOptions.find((item) => item.type === type);
726
857
  return { _id: idCreator(), type, name: createDefaultFieldName(aiTable, fieldOption) };
727
858
  }
728
859
 
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
860
  function getFieldValue(record, field) {
761
861
  if (isSystemField(field)) {
762
862
  return getSystemFieldValue(record, field.type);
@@ -821,7 +921,7 @@ const AITableQueries = {
821
921
  if (!path) {
822
922
  throw new Error(`path does not exist as path [${path}]`);
823
923
  }
824
- return aiTable.fields().find((item) => item._id === path[0]);
924
+ return aiTable.gridData().fields.find((item) => item._id === path[0]);
825
925
  },
826
926
  getRecord(aiTable, path) {
827
927
  if (!aiTable) {
@@ -917,6 +1017,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
917
1017
  }] } });
918
1018
 
919
1019
  class DateCellEditorComponent extends AbstractEditCellEditor {
1020
+ constructor() {
1021
+ super(...arguments);
1022
+ this.placeholder = '';
1023
+ }
920
1024
  ngOnInit() {
921
1025
  this.modelValue = computed(() => {
922
1026
  const value = AITableQueries.getFieldValue(this.aiTable, [this.record()._id, this.field()._id]);
@@ -927,6 +1031,7 @@ class DateCellEditorComponent extends AbstractEditCellEditor {
927
1031
  }
928
1032
  return value;
929
1033
  })();
1034
+ this.placeholder = getI18nTextByKey(this.aiTable, AITableGridI18nKey.dataPickerPlaceholder);
930
1035
  }
931
1036
  updateValue(value) {
932
1037
  this.updateFieldValue.emit({
@@ -945,7 +1050,7 @@ class DateCellEditorComponent extends AbstractEditCellEditor {
945
1050
  <thy-date-picker
946
1051
  class="h-100"
947
1052
  thyTimestampPrecision="seconds"
948
- thyPlaceHolder="选择日期"
1053
+ [thyPlaceHolder]="placeholder"
949
1054
  [ngModel]="modelValue.timestamp"
950
1055
  (ngModelChange)="updateValue($event)"
951
1056
  (thyOpenChange)="thyOpenChange($event)"
@@ -967,7 +1072,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
967
1072
  <thy-date-picker
968
1073
  class="h-100"
969
1074
  thyTimestampPrecision="seconds"
970
- thyPlaceHolder="选择日期"
1075
+ [thyPlaceHolder]="placeholder"
971
1076
  [ngModel]="modelValue.timestamp"
972
1077
  (ngModelChange)="updateValue($event)"
973
1078
  (thyOpenChange)="thyOpenChange($event)"
@@ -998,23 +1103,37 @@ class LinkEditComponent {
998
1103
  this.thyPopoverRef = thyPopoverRef;
999
1104
  this.url = '';
1000
1105
  this.text = '';
1106
+ this.aiTable = input();
1001
1107
  this.confirm = new EventEmitter();
1002
1108
  this.URLRegex = LINK_URL_REGEX;
1003
- this.validatorConfig = {
1004
- validationMessages: {
1005
- url: {
1006
- pattern: '链接格式不正确'
1109
+ this.i18nTexts = computed(() => {
1110
+ return {
1111
+ linkText: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.linkText),
1112
+ textPlaceholder: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.inputText),
1113
+ urlLabel: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.linkUrl),
1114
+ urlPlaceholder: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.inputUrl),
1115
+ cancel: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.cancel),
1116
+ apply: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.apply)
1117
+ };
1118
+ });
1119
+ this.validatorConfig = computed(() => {
1120
+ return {
1121
+ validationMessages: {
1122
+ url: {
1123
+ pattern: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.invalidLinkFormat)
1124
+ }
1007
1125
  }
1008
- }
1009
- };
1126
+ };
1127
+ });
1128
+ }
1129
+ ngOnInit() {
1010
1130
  }
1011
- ngOnInit() { }
1012
1131
  close() {
1013
1132
  this.thyPopoverRef.close();
1014
1133
  }
1015
1134
  apply(form) {
1016
1135
  if (this.text && !this.url) {
1017
- form.validator.setElementErrorMessage('url', '链接不能为空');
1136
+ form.validator.setElementErrorMessage('url', getI18nTextByKey(this.aiTable(), AITableGridI18nKey.linkRequired));
1018
1137
  return;
1019
1138
  }
1020
1139
  this.close();
@@ -1024,7 +1143,7 @@ class LinkEditComponent {
1024
1143
  this.confirm.emit(link);
1025
1144
  }
1026
1145
  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"] }] }); }
1146
+ 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
1147
  }
1029
1148
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LinkEditComponent, decorators: [{
1030
1149
  type: Component,
@@ -1036,7 +1155,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1036
1155
  ThyButton,
1037
1156
  ThyFormSubmitDirective,
1038
1157
  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" }]
1158
+ ], 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
1159
  }], ctorParameters: () => [{ type: i1$1.ThyPopoverRef }], propDecorators: { url: [{
1041
1160
  type: Input
1042
1161
  }], text: [{
@@ -1055,6 +1174,9 @@ class LinkCellEditorComponent extends AbstractEditCellEditor {
1055
1174
  this.cdr = inject(ChangeDetectorRef);
1056
1175
  this.notifyService = inject(ThyNotifyService);
1057
1176
  this.isOpened = false;
1177
+ this.linkTooltip = computed(() => {
1178
+ return getI18nTextByKey(this.aiTable, AITableGridI18nKey.linkTooltip);
1179
+ });
1058
1180
  }
1059
1181
  isValidLink(link) {
1060
1182
  if (!link?.text?.trim()) {
@@ -1089,7 +1211,7 @@ class LinkCellEditorComponent extends AbstractEditCellEditor {
1089
1211
  }
1090
1212
  updateValue() {
1091
1213
  if (!this.isValidLink({ text: this.text, url: this.url ?? '' })) {
1092
- this.notifyService.error('链接格式不正确');
1214
+ this.notifyService.error(getI18nTextByKey(this.aiTable, AITableGridI18nKey.invalidLinkFormat));
1093
1215
  return;
1094
1216
  }
1095
1217
  this.modelValue = this.createLinkValue({ text: this.text, url: this.url ?? '' });
@@ -1108,7 +1230,8 @@ class LinkCellEditorComponent extends AbstractEditCellEditor {
1108
1230
  width: this.elementRef.nativeElement.clientWidth + 'px',
1109
1231
  initialState: {
1110
1232
  url: this.url ?? '',
1111
- text: this.text ?? ''
1233
+ text: this.text ?? '',
1234
+ aiTable: this.aiTable
1112
1235
  }
1113
1236
  });
1114
1237
  if (popoverRef) {
@@ -1124,7 +1247,7 @@ class LinkCellEditorComponent extends AbstractEditCellEditor {
1124
1247
  }
1125
1248
  }
1126
1249
  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 }); }
1250
+ 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
1251
  }
1129
1252
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LinkCellEditorComponent, decorators: [{
1130
1253
  type: Component,
@@ -1136,11 +1259,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1136
1259
  ThyTooltipModule,
1137
1260
  ThyAction,
1138
1261
  ThyInputModule,
1139
- ThyFlexibleTextModule,
1140
- LinkEditComponent
1262
+ ThyFlexibleTextModule
1141
1263
  ], host: {
1142
1264
  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" }]
1265
+ }, 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
1266
  }], propDecorators: { inputElement: [{
1145
1267
  type: ViewChild,
1146
1268
  args: ['inputElement', { static: false }]
@@ -1529,18 +1651,22 @@ class AITableFieldSetting {
1529
1651
  this.addField = output();
1530
1652
  this.setField = output();
1531
1653
  this.selectedFieldOption = computed(() => {
1532
- return getFieldOptionByField(this.aiEditField());
1654
+ return getFieldOptionByField(this.aiTable(), this.aiEditField());
1533
1655
  });
1534
1656
  this.fieldMaxLength = 32;
1535
- this.validatorConfig = {
1536
- validationMessages: {
1537
- fieldName: {
1538
- required: '列名不能为空',
1539
- thyUniqueCheck: '列名已存在'
1657
+ this.validatorConfig = computed(() => {
1658
+ return {
1659
+ validationMessages: {
1660
+ fieldName: {
1661
+ required: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldNameRequired),
1662
+ thyUniqueCheck: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldNameDuplicate)
1663
+ }
1540
1664
  }
1541
- }
1542
- };
1543
- this.fieldOptions = _.cloneDeep(FieldOptions);
1665
+ };
1666
+ });
1667
+ this.fieldOptions = computed(() => {
1668
+ return getFieldOptions(this.aiTable());
1669
+ });
1544
1670
  this.aITableFieldType = AITableFieldType;
1545
1671
  this.isMultipleMember = false;
1546
1672
  this.thyPopoverRef = inject((ThyPopoverRef));
@@ -1550,14 +1676,25 @@ class AITableFieldSetting {
1550
1676
  .fields()
1551
1677
  ?.find((field) => field.name === fieldName && this.aiEditField()?._id !== field._id));
1552
1678
  };
1679
+ this.i18nTexts = computed(() => {
1680
+ return {
1681
+ columnName: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldColumnName),
1682
+ columnNamePlaceholder: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldColumnNamePlaceholder),
1683
+ fieldType: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.fieldType),
1684
+ allowMultipleMembers: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.allowMultipleMembers),
1685
+ cancel: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.cancel),
1686
+ confirm: getI18nTextByKey(this.aiTable(), AITableGridI18nKey.confirm)
1687
+ };
1688
+ });
1553
1689
  }
1554
1690
  ngOnInit() {
1555
1691
  this.isMultipleMember =
1556
1692
  this.aiEditField().type === AITableFieldType.member && !!this.aiEditField().settings?.is_multiple;
1557
1693
  }
1558
1694
  selectFieldType(field) {
1695
+ const fieldsSizeMap = this.aiTable().gridData().fieldsSizeMap;
1559
1696
  this.aiEditField.update((item) => {
1560
- const width = item.width ?? field.width;
1697
+ const width = fieldsSizeMap[item._id] ?? field.width;
1561
1698
  const settings = field.settings || {};
1562
1699
  const name = createDefaultFieldName(this.aiTable(), field);
1563
1700
  return { ...item, ...field, width, name, settings };
@@ -1595,7 +1732,7 @@ class AITableFieldSetting {
1595
1732
  this.thyPopoverRef.close();
1596
1733
  }
1597
1734
  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 }); }
1735
+ 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
1736
  }
1600
1737
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableFieldSetting, decorators: [{
1601
1738
  type: Component,
@@ -1621,7 +1758,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1621
1758
  AITableFieldIsSameOptionPipe
1622
1759
  ], host: {
1623
1760
  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"] }]
1761
+ }, 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
1762
  }] });
1626
1763
 
1627
1764
  class AITableGridSelectionService {
@@ -1670,6 +1807,9 @@ class AITableGridSelectionService {
1670
1807
  drag(config) {
1671
1808
  this.aiTable.dragState.set(config);
1672
1809
  }
1810
+ getDragStateType() {
1811
+ return this.aiTable.dragState?.()?.type;
1812
+ }
1673
1813
  clearDrag() {
1674
1814
  this.aiTable.dragState.set({
1675
1815
  type: DragType.none,
@@ -1838,6 +1978,7 @@ const AI_TABLE_FIELD_ADD_BUTTON = 'AI_TABLE_FIELD_ADD_BUTTON'; // 添加列名
1838
1978
  const AI_TABLE_FIELD_ADD_BUTTON_WIDTH = 100; // 添加列宽度
1839
1979
  const AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE = 8; // 字段表列头图标的间距
1840
1980
  const AI_TABLE_FIELD_HEAD_MORE = 'AI_TABLE_FIELD_HEAD_MORE'; // 更多图标名称
1981
+ const AI_TABLE_FIELD_HEAD_OPACITY_LINE = 'AI_TABLE_FIELD_HEAD_OPACITY_LINE'; // 字段列头透明线
1841
1982
  const AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS = '.ai-table-prevent-clear-selection';
1842
1983
  const AI_TABLE_ICON_COMMON_SIZE = 16; // 表格图标的通用尺寸
1843
1984
  const AI_TABLE_CELL = 'AI_TABLE_CELL'; // 单元格标识
@@ -2027,13 +2168,13 @@ const buildGridLinearRows = (visibleRecords, isAddingVisible = true) => {
2027
2168
  });
2028
2169
  return linearRows;
2029
2170
  };
2030
- const buildGridData = (recordValue, fieldsValue) => {
2171
+ const buildGridData = (aiTable, recordValue, fieldsValue) => {
2172
+ const fieldOptions = getFieldOptions(aiTable);
2031
2173
  const fields = fieldsValue.map((value) => {
2032
- const fieldOption = FieldOptions.find((item) => item.type === value.type);
2174
+ const fieldOption = fieldOptions.find((item) => item.type === value.type);
2033
2175
  return {
2034
2176
  ...value,
2035
- icon: value.icon || fieldOption.icon,
2036
- width: value.width || fieldOption.width
2177
+ icon: value.icon || fieldOption.icon
2037
2178
  };
2038
2179
  });
2039
2180
  return {
@@ -2094,10 +2235,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2094
2235
  type: Injectable
2095
2236
  }], ctorParameters: () => [{ type: i1$1.ThyPopover }] });
2096
2237
 
2097
- function getColumnIndicesSizeMap(fields) {
2238
+ function getColumnIndicesSizeMap(aiTable, fields) {
2239
+ const fieldSizeMap = aiTable.gridData().fieldsSizeMap;
2098
2240
  const columnIndicesSizeMap = {};
2099
2241
  fields?.forEach((field, index) => {
2100
- columnIndicesSizeMap[index] = field.width ?? getFieldOptionByField(field).width;
2242
+ columnIndicesSizeMap[index] = fieldSizeMap[field._id] ?? getFieldOptionByField(aiTable, field).width;
2101
2243
  });
2102
2244
  return columnIndicesSizeMap;
2103
2245
  }
@@ -3121,6 +3263,7 @@ function toSelectFieldValue(plainText, targetField, originData) {
3121
3263
  }
3122
3264
  function processPastedValueForSelect(plainText, targetField, originData) {
3123
3265
  const targetFieldOptions = targetField.settings?.options || [];
3266
+ const targetOptionStyle = targetField.settings?.option_style || AITableSelectOptionStyle.text;
3124
3267
  let existOptionIds = [];
3125
3268
  let newOptions = [];
3126
3269
  let cellFullTexts = plainText.split(',').map((text) => text.trim());
@@ -3140,12 +3283,8 @@ function processPastedValueForSelect(plainText, targetField, originData) {
3140
3283
  else {
3141
3284
  const originOption = originOptionsMap[id];
3142
3285
  if (originOption) {
3143
- newOptions.push({
3144
- text: originOption.text,
3145
- icon: originOption.icon,
3146
- color: originOption.color,
3147
- bg_color: originOption.bg_color
3148
- });
3286
+ const newOption = copyOption(originOption, targetFieldOptions, targetOptionStyle);
3287
+ newOptions.push(newOption);
3149
3288
  }
3150
3289
  }
3151
3290
  });
@@ -3154,7 +3293,14 @@ function processPastedValueForSelect(plainText, targetField, originData) {
3154
3293
  else {
3155
3294
  cellFullTexts.forEach((text) => {
3156
3295
  const option = targetFieldOptions.find((option) => option.text === text);
3157
- option ? existOptionIds.push(option._id) : newOptions.push({ text });
3296
+ if (option) {
3297
+ existOptionIds.push(option._id);
3298
+ }
3299
+ else {
3300
+ const originOption = { text };
3301
+ const newOption = copyOption(originOption, targetFieldOptions, targetOptionStyle);
3302
+ newOptions.push(newOption);
3303
+ }
3158
3304
  });
3159
3305
  }
3160
3306
  const isMultiple = targetField.settings?.is_multiple;
@@ -3175,6 +3321,22 @@ function processPastedValueForSelect(plainText, targetField, originData) {
3175
3321
  }
3176
3322
  }
3177
3323
  }
3324
+ function copyOption(originOption, targetFieldOptions, targetOptionStyle) {
3325
+ let newOption = {
3326
+ _id: idCreator(),
3327
+ text: originOption.text
3328
+ };
3329
+ if (targetOptionStyle !== AITableSelectOptionStyle.text) {
3330
+ const originBgColor = originOption.bg_color;
3331
+ const existBgColors = targetFieldOptions.map((option) => option.bg_color);
3332
+ const defaultBgColor = DEFAULT_COLORS[10 + (targetFieldOptions?.length || 0)];
3333
+ newOption = {
3334
+ ...newOption,
3335
+ bg_color: originBgColor && !existBgColors.includes(originBgColor) ? originBgColor : defaultBgColor
3336
+ };
3337
+ }
3338
+ return newOption;
3339
+ }
3178
3340
  function cellValueToSortValue$1(cellValue, field) {
3179
3341
  if (!cellValue) {
3180
3342
  return null;
@@ -3422,12 +3584,6 @@ function getPasteValue(plainText, aiTableContent, recordIndex, fieldIndex, targe
3422
3584
  let newField = null;
3423
3585
  let newOptionIds = [];
3424
3586
  if (newOptions.length) {
3425
- newOptions = newOptions.map((option) => {
3426
- return {
3427
- ...option,
3428
- _id: idCreator()
3429
- };
3430
- });
3431
3587
  newField = {
3432
3588
  ...targetField,
3433
3589
  settings: {
@@ -3457,9 +3613,10 @@ function appendField(aiTable, originField, actions) {
3457
3613
  const lastFieldId = fields.length > 0 ? fields[fields.length - 1]._id : '';
3458
3614
  let defaultFieldValue;
3459
3615
  if (originField) {
3616
+ const fieldOptions = getFieldOptions(aiTable);
3460
3617
  defaultFieldValue = {
3461
3618
  ...originField,
3462
- name: createDefaultFieldName(aiTable, FieldOptions.find((item) => item.type === originField.type)),
3619
+ name: createDefaultFieldName(aiTable, fieldOptions.find((item) => item.type === originField.type)),
3463
3620
  _id: idCreator()
3464
3621
  };
3465
3622
  }
@@ -3550,15 +3707,15 @@ const getVisibleRangeInfo = (coordinate, scrollState) => {
3550
3707
  columnStopIndex
3551
3708
  };
3552
3709
  };
3553
- const scrollMax = (coordinate, visibleColumns) => {
3554
- const scrollMaxWidth = visibleColumns.reduce((pre, cur) => pre + getFieldOptionByField(cur)?.width, AI_TABLE_ROW_HEAD_WIDTH);
3710
+ const scrollMax = (aiTable, coordinate, visibleColumns) => {
3711
+ const scrollMaxWidth = visibleColumns.reduce((pre, cur) => pre + getFieldOptionByField(aiTable, cur)?.width, AI_TABLE_ROW_HEAD_WIDTH);
3555
3712
  const scrollMaxHeight = coordinate.getRowOffset(coordinate.rowCount - 1) + 32;
3556
3713
  return { scrollMaxWidth, scrollMaxHeight };
3557
3714
  };
3558
3715
 
3559
- const getMousePosition = (x, y, coordinate, fields, context, _targetName) => {
3716
+ const getMousePosition = (aiTable, x, y, coordinate, fields, context, _targetName) => {
3560
3717
  const { scrollTop, scrollLeft } = context.scrollState();
3561
- const { scrollMaxWidth, scrollMaxHeight } = scrollMax(coordinate, fields);
3718
+ const { scrollMaxWidth, scrollMaxHeight } = scrollMax(aiTable, coordinate, fields);
3562
3719
  const offsetTop = scrollTop + y;
3563
3720
  const rowIndex = coordinate.getRowStartIndex(offsetTop);
3564
3721
  const offsetLeft = isWithinFrozenColumnBoundary(x, coordinate.frozenColumnWidth) ? x : scrollLeft + x;
@@ -5091,7 +5248,7 @@ class AITableCellLink {
5091
5248
  return;
5092
5249
  const { context } = aiTable;
5093
5250
  const { x, y } = pos;
5094
- const curMousePosition = getMousePosition(x, y, coordinate, AITable.getVisibleFields(aiTable), context, targetName);
5251
+ const curMousePosition = getMousePosition(aiTable, x, y, coordinate, AITable.getVisibleFields(aiTable), context, targetName);
5095
5252
  handleMouseStyle(AI_TABLE_FIELD_HEAD_MORE, curMousePosition.areaType, coordinate.container);
5096
5253
  }
5097
5254
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableCellLink, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
@@ -6205,12 +6362,14 @@ class AITableGridBase {
6205
6362
  constructor() {
6206
6363
  this.aiRecords = model.required();
6207
6364
  this.aiFields = model.required();
6208
- this.aiContextMenuItems = input([]);
6365
+ this.aiFieldsSizeMap = model.required();
6366
+ this.aiContextMenuItems = input();
6209
6367
  this.aiFieldConfig = input();
6210
6368
  this.aiReadonly = input();
6211
6369
  this.aiPlugins = input();
6212
6370
  this.aiReferences = input.required();
6213
6371
  this.aiBuildRenderDataFn = input();
6372
+ this.aiGetI18nTextByKey = input();
6214
6373
  this.aiKeywords = input();
6215
6374
  this.AITableFieldType = AITableFieldType;
6216
6375
  this.AITableSelectOptionStyle = AITableSelectOptionStyle;
@@ -6223,10 +6382,15 @@ class AITableGridBase {
6223
6382
  this.aiMoveField = output();
6224
6383
  this.aiUpdateFieldValue = output();
6225
6384
  this.aiSetField = output();
6385
+ this.aiSetFieldWidth = output();
6226
6386
  this.aiClick = output();
6227
6387
  this.aiDbClick = output();
6228
6388
  this.fieldMenus = computed(() => {
6229
- return this.aiFieldConfig()?.fieldMenus || [];
6389
+ const fieldMenusFn = this.aiFieldConfig()?.fieldMenus;
6390
+ if (fieldMenusFn && this.aiTable) {
6391
+ return fieldMenusFn(this.aiTable);
6392
+ }
6393
+ return [];
6230
6394
  });
6231
6395
  this.gridData = computed(() => {
6232
6396
  if (this.aiBuildRenderDataFn && this.aiBuildRenderDataFn() && this.aiTable) {
@@ -6234,7 +6398,8 @@ class AITableGridBase {
6234
6398
  }
6235
6399
  return {
6236
6400
  records: this.aiRecords(),
6237
- fields: this.aiFields()
6401
+ fields: this.aiFields(),
6402
+ fieldsSizeMap: this.aiFieldsSizeMap()
6238
6403
  };
6239
6404
  });
6240
6405
  this.ngZone = inject(NgZone);
@@ -6250,6 +6415,9 @@ class AITableGridBase {
6250
6415
  }
6251
6416
  initAITable() {
6252
6417
  this.aiTable = createAITable(this.aiRecords, this.aiFields, this.gridData);
6418
+ if (this.aiGetI18nTextByKey()) {
6419
+ this.aiTable.getI18nTextByKey = this.aiGetI18nTextByKey();
6420
+ }
6253
6421
  this.aiPlugins()?.forEach((plugin) => {
6254
6422
  this.aiTable = plugin(this.aiTable);
6255
6423
  });
@@ -6339,7 +6507,7 @@ class AITableGridBase {
6339
6507
  }
6340
6508
  }
6341
6509
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6342
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableGridBase, isStandalone: true, selector: "ai-table-grid-base", inputs: { aiRecords: { classPropertyName: "aiRecords", publicName: "aiRecords", isSignal: true, isRequired: true, transformFunction: null }, aiFields: { classPropertyName: "aiFields", publicName: "aiFields", isSignal: true, isRequired: true, transformFunction: null }, aiContextMenuItems: { classPropertyName: "aiContextMenuItems", publicName: "aiContextMenuItems", isSignal: true, isRequired: false, transformFunction: null }, aiFieldConfig: { classPropertyName: "aiFieldConfig", publicName: "aiFieldConfig", isSignal: true, isRequired: false, transformFunction: null }, aiReadonly: { classPropertyName: "aiReadonly", publicName: "aiReadonly", isSignal: true, isRequired: false, transformFunction: null }, aiPlugins: { classPropertyName: "aiPlugins", publicName: "aiPlugins", isSignal: true, isRequired: false, transformFunction: null }, aiReferences: { classPropertyName: "aiReferences", publicName: "aiReferences", isSignal: true, isRequired: true, transformFunction: null }, aiBuildRenderDataFn: { classPropertyName: "aiBuildRenderDataFn", publicName: "aiBuildRenderDataFn", isSignal: true, isRequired: false, transformFunction: null }, aiKeywords: { classPropertyName: "aiKeywords", publicName: "aiKeywords", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiRecords: "aiRecordsChange", aiFields: "aiFieldsChange", aiTableInitialized: "aiTableInitialized", aiAddRecord: "aiAddRecord", aiAddField: "aiAddField", aiMoveField: "aiMoveField", aiUpdateFieldValue: "aiUpdateFieldValue", aiSetField: "aiSetField", aiClick: "aiClick", aiDbClick: "aiDbClick" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6510
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AITableGridBase, isStandalone: true, selector: "ai-table-grid-base", inputs: { aiRecords: { classPropertyName: "aiRecords", publicName: "aiRecords", isSignal: true, isRequired: true, transformFunction: null }, aiFields: { classPropertyName: "aiFields", publicName: "aiFields", isSignal: true, isRequired: true, transformFunction: null }, aiFieldsSizeMap: { classPropertyName: "aiFieldsSizeMap", publicName: "aiFieldsSizeMap", isSignal: true, isRequired: true, transformFunction: null }, aiContextMenuItems: { classPropertyName: "aiContextMenuItems", publicName: "aiContextMenuItems", isSignal: true, isRequired: false, transformFunction: null }, aiFieldConfig: { classPropertyName: "aiFieldConfig", publicName: "aiFieldConfig", isSignal: true, isRequired: false, transformFunction: null }, aiReadonly: { classPropertyName: "aiReadonly", publicName: "aiReadonly", isSignal: true, isRequired: false, transformFunction: null }, aiPlugins: { classPropertyName: "aiPlugins", publicName: "aiPlugins", isSignal: true, isRequired: false, transformFunction: null }, aiReferences: { classPropertyName: "aiReferences", publicName: "aiReferences", isSignal: true, isRequired: true, transformFunction: null }, aiBuildRenderDataFn: { classPropertyName: "aiBuildRenderDataFn", publicName: "aiBuildRenderDataFn", isSignal: true, isRequired: false, transformFunction: null }, aiGetI18nTextByKey: { classPropertyName: "aiGetI18nTextByKey", publicName: "aiGetI18nTextByKey", isSignal: true, isRequired: false, transformFunction: null }, aiKeywords: { classPropertyName: "aiKeywords", publicName: "aiKeywords", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { aiRecords: "aiRecordsChange", aiFields: "aiFieldsChange", aiFieldsSizeMap: "aiFieldsSizeMapChange", aiTableInitialized: "aiTableInitialized", aiAddRecord: "aiAddRecord", aiAddField: "aiAddField", aiMoveField: "aiMoveField", aiUpdateFieldValue: "aiUpdateFieldValue", aiSetField: "aiSetField", aiSetFieldWidth: "aiSetFieldWidth", aiClick: "aiClick", aiDbClick: "aiDbClick" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6343
6511
  }
6344
6512
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableGridBase, decorators: [{
6345
6513
  type: Component,
@@ -6366,7 +6534,7 @@ class AITableDomGrid extends AITableGridBase {
6366
6534
  });
6367
6535
  }
6368
6536
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
6369
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableDomGrid, isStandalone: true, selector: "ai-table-dom-grid", host: { classAttribute: "ai-table-grid ai-table-dom-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], usesInheritance: true, ngImport: i0, template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SelectOptionPipe, name: "selectOption" }, { kind: "pipe", type: SelectOptionsPipe, name: "selectOptions" }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "ngmodule", type: ThyPopoverModule }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyRate, selector: "thy-rate", inputs: ["thyCount", "thyDisabled", "thyAllowHalf", "thyAllowClear", "thyTooltips", "thyIconTemplate"], outputs: ["thyItemHoverChange"] }, { kind: "component", type: ThyProgress, selector: "thy-progress", inputs: ["thyType", "thySize", "thyValue", "thyMax", "thyTips", "thyShape", "thyGapDegree", "thyGapPosition", "thyStrokeWidth"] }, { kind: "pipe", type: ThyDatePickerFormatPipe, name: "thyDatePickerFormat" }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyCheckboxModule }, { kind: "component", type: i3$1.ThyCheckbox, selector: "thy-checkbox,[thy-checkbox],[thyCheckbox]", inputs: ["thyIndeterminate"] }, { kind: "ngmodule", type: ThyAvatarModule }, { kind: "component", type: i4.ThyAvatar, selector: "thy-avatar", inputs: ["thyShowName", "thySrc", "thyName", "thySize", "thyShowRemove", "thyRemovable", "thyImgClass", "thyDisabled", "thyLoading", "thyFetchPriority"], outputs: ["thyOnRemove", "thyRemove", "thyError"] }, { kind: "component", type: i4.ThyAvatarList, selector: "thy-avatar-list", inputs: ["thyMode", "thyAvatarSize"] }, { kind: "pipe", type: IsSelectRecordPipe, name: "isSelectRecord" }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "pipe", type: UserPipe, name: "user" }, { kind: "pipe", type: SelectSettingPipe, name: "selectSetting" }, { kind: "pipe", type: MemberSettingPipe, name: "memberSetting" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6537
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableDomGrid, isStandalone: true, selector: "ai-table-dom-grid", host: { classAttribute: "ai-table-grid ai-table-dom-grid" }, providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], usesInheritance: true, ngImport: i0, template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: gridData().fieldsSizeMap[field._id] + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: gridData().fieldsSizeMap[field._id] + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SelectOptionPipe, name: "selectOption" }, { kind: "pipe", type: SelectOptionsPipe, name: "selectOptions" }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "ngmodule", type: ThyPopoverModule }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyRate, selector: "thy-rate", inputs: ["thyCount", "thyDisabled", "thyAllowHalf", "thyAllowClear", "thyTooltips", "thyIconTemplate"], outputs: ["thyItemHoverChange"] }, { kind: "component", type: ThyProgress, selector: "thy-progress", inputs: ["thyType", "thySize", "thyValue", "thyMax", "thyTips", "thyShape", "thyGapDegree", "thyGapPosition", "thyStrokeWidth"] }, { kind: "pipe", type: ThyDatePickerFormatPipe, name: "thyDatePickerFormat" }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "ngmodule", type: ThyCheckboxModule }, { kind: "component", type: i3$1.ThyCheckbox, selector: "thy-checkbox,[thy-checkbox],[thyCheckbox]", inputs: ["thyIndeterminate"] }, { kind: "ngmodule", type: ThyAvatarModule }, { kind: "component", type: i4.ThyAvatar, selector: "thy-avatar", inputs: ["thyShowName", "thySrc", "thyName", "thySize", "thyShowRemove", "thyRemovable", "thyImgClass", "thyDisabled", "thyLoading", "thyFetchPriority"], outputs: ["thyOnRemove", "thyRemove", "thyError"] }, { kind: "component", type: i4.ThyAvatarList, selector: "thy-avatar-list", inputs: ["thyMode", "thyAvatarSize"] }, { kind: "pipe", type: IsSelectRecordPipe, name: "isSelectRecord" }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "pipe", type: UserPipe, name: "user" }, { kind: "pipe", type: SelectSettingPipe, name: "selectSetting" }, { kind: "pipe", type: MemberSettingPipe, name: "memberSetting" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6370
6538
  }
6371
6539
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDomGrid, decorators: [{
6372
6540
  type: Component,
@@ -6402,7 +6570,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
6402
6570
  UserPipe,
6403
6571
  SelectSettingPipe,
6404
6572
  MemberSettingPipe
6405
- ], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: field.width + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n" }]
6573
+ ], providers: [AITableGridEventService, AITableGridFieldService, AITableGridSelectionService], template: "<div class=\"grid-header d-flex\">\n <div class=\"grid-column-checkbox grid-cell grid-checkbox\">\n <label thyCheckbox thyLabelText=\"\" [ngModel]=\"isSelectedAll()\" (ngModelChange)=\"toggleSelectAll($event)\"></label>\n </div>\n @for (field of gridData().fields; track field._id) {\n <div\n class=\"grid-cell grid-field\"\n #fieldAction\n [attr.fieldId]=\"field._id\"\n [ngClass]=\"{ highlight: aiTable.selection().selectedFields.has(field._id) }\"\n [ngStyle]=\"{ width: gridData().fieldsSizeMap[field._id] + 'px' }\"\n >\n <span class=\"text-truncate\">\n <thy-icon [thyIconName]=\"field.icon!\" class=\"mr-2 text-muted\"></thy-icon>\n <span>{{ field.name }}</span>\n </span>\n <a\n href=\"javascript:;\"\n class=\"grid-field-action\"\n thyAction\n thyIcon=\"more-vertical\"\n (click)=\"openFieldMenu($event, field, fieldAction)\"\n >\n </a>\n </div>\n }\n <div class=\"grid-column-blank cursor-pointer\" #gridColumnBlank (click)=\"addField(gridColumnBlank)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n<div class=\"grid-body d-flex\">\n @for (record of gridData().records; track record._id; let index = $index) {\n <div class=\"grid-row d-flex\" [ngClass]=\"{ highlight: (record._id | isSelectRecord: aiTable.selection()) }\">\n <div class=\"grid-row-index grid-checkbox\">\n <label\n [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'checked-box' : 'unchecked-box'\"\n thyCheckbox\n thyLabelText=\"\"\n [ngModel]=\"record._id | isSelectRecord: aiTable.selection()\"\n (ngModelChange)=\"selectRecord(record._id)\"\n ></label>\n <span [ngClass]=\"(record._id | isSelectRecord: aiTable.selection()) ? 'grid-row-no-number' : 'grid-row-number'\">\n {{ index + 1 }}\n </span>\n </div>\n @for (field of gridData().fields; track field._id) {\n <!-- [ngClass]=\"{\n highlight: aiTable.selection().selectedCells.has(record._id) || aiTable.selection().selectedFields.has(field._id),\n selected: aiTable.selection().selectedCells.get(record._id)?.hasOwnProperty(field._id)\n }\" -->\n <div\n #cell\n class=\"grid-cell\"\n [attr.type]=\"[field.type]\"\n [attr.fieldId]=\"[field._id]\"\n [attr.recordId]=\"[record._id]\"\n [ngStyle]=\"{ width: gridData().fieldsSizeMap[field._id] + 'px' }\"\n >\n @switch (field.type) {\n @case (AITableFieldType.select) {\n @let fieldValue = record.values[field._id];\n @let settings = field.settings! | selectSetting;\n @let options = settings['options'];\n @let optionStyle = settings['option_style'] || AITableSelectOptionStyle.tag;\n @let isTagStyle = optionStyle === AITableSelectOptionStyle.tag;\n\n @if (!settings['is_multiple'] && fieldValue | selectOption: options; as selectedOption) {\n @if (isTagStyle) {\n <select-option class=\"mb-1 mr-1\" [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"selectedOption\"></select-option>\n </div>\n }\n } @else {\n @let maxShowCount = 2;\n\n <div class=\"d-flex\">\n @if (fieldValue | selectOptions: options; as selectedOptions) {\n @for (option of selectedOptions; track option!._id; let i = $index) {\n @if (i + 1 <= maxShowCount) {\n @if (isTagStyle) {\n <select-option\n class=\"mb-1 mr-1\"\n [field]=\"field\"\n [displayOption]=\"option!\"\n ></select-option>\n } @else {\n <div thyTag class=\"mb-1 mr-1\">\n <select-option [field]=\"field\" [displayOption]=\"option!\"></select-option>\n </div>\n }\n }\n }\n\n @let selectedLength = selectedOptions.length || 0;\n @if (selectedOptions && maxShowCount < selectedLength) {\n @let shape = isTagStyle ? 'pill' : 'rectangle';\n @let isHidden = maxShowCount >= selectedLength;\n\n <thy-tag\n class=\"cursor-pointer\"\n [class.multi-property-value-hidden]=\"isHidden\"\n [thyShape]=\"shape\"\n >\n <span class=\"text-truncate\"> +{{ selectedLength - maxShowCount }} </span>\n </thy-tag>\n }\n }\n </div>\n }\n }\n @case (AITableFieldType.date) {\n {{ record.values[field._id].timestamp | thyDatePickerFormat }}\n }\n @case (AITableFieldType.updatedAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.createdAt) {\n <div class=\"d-block user-select-none\">\n <span class=\"text-truncate\">\n {{ record.values[field._id] | thyDatePickerFormat: 'yyyy-MM-dd HH:mm' }}\n </span>\n </div>\n }\n @case (AITableFieldType.rate) {\n <thy-rate [ngModel]=\"record.values[field._id]\"></thy-rate>\n }\n @case (AITableFieldType.link) {\n <a\n class=\"d-block\"\n target=\"_blank\"\n [href]=\"record.values[field._id]?.url\"\n thyStopPropagation\n thyFlexibleText\n [thyTooltipContent]=\"record.values[field._id]?.text\"\n >\n {{ record.values[field._id]?.text }}\n </a>\n }\n @case (AITableFieldType.progress) {\n <thy-progress\n class=\"w-100\"\n [thyValue]=\"record.values[field._id] || 0\"\n [thySize]=\"record.values[field._id]?.config?.size || 'md'\"\n [thyMax]=\"record.values[field._id]?.config?.max || 100\"\n [thyType]=\"record.values[field._id]?.config?.progressType || 'success'\"\n >\n <span> {{ record.values[field._id] || 0 }}{{ record.values[field._id]?.config?.suffix || '%' }} </span>\n </thy-progress>\n }\n @case (AITableFieldType.member) {\n @let settings = field.settings! | memberSetting;\n\n @if (!settings!['is_multiple']) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n } @else {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n <thy-avatar-list thyAvatarSize=\"xs\">\n @for (item of recordValues; track $index) {\n <thy-avatar [thyName]=\"item.display_name!\" [thySrc]=\"item.avatar!\"></thy-avatar>\n }\n </thy-avatar-list>\n }\n }\n @case (AITableFieldType.createdBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @case (AITableFieldType.updatedBy) {\n @let recordValues = record.values[field._id] | user: aiReferences()!;\n\n @if (recordValues && recordValues.length) {\n <thy-avatar\n [thyName]=\"recordValues[0].display_name!\"\n [thySrc]=\"recordValues[0].avatar!\"\n thySize=\"xs\"\n thyShowName=\"true\"\n ></thy-avatar>\n }\n }\n @default {\n <span class=\"text-truncate\"> {{ record.values[field._id] }}</span>\n }\n }\n <div class=\"autofill-container\"></div>\n </div>\n }\n <div class=\"grid-column-blank\"></div>\n </div>\n }\n <div class=\"grid-row-insert grid-row cursor-pointer\" (click)=\"addRecord()\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n </div>\n</div>\n\n<div #activeBorder class=\"active-border\"></div>\n" }]
6406
6574
  }] });
6407
6575
 
6408
6576
  class AITableIcon {
@@ -7858,6 +8026,20 @@ class AITableFieldHead {
7858
8026
  cornerRadius: 4
7859
8027
  };
7860
8028
  });
8029
+ this.fieldOpacityLineConfig = computed(() => {
8030
+ const { field, width, height } = this.config();
8031
+ return {
8032
+ x: AI_TABLE_OFFSET + width,
8033
+ y: AI_TABLE_OFFSET,
8034
+ name: generateTargetName({
8035
+ targetName: AI_TABLE_FIELD_HEAD_OPACITY_LINE,
8036
+ fieldId: field._id
8037
+ }),
8038
+ points: [0, 0, 0, height],
8039
+ stroke: Colors.transparent,
8040
+ strokeWidth: 6
8041
+ };
8042
+ });
7861
8043
  }
7862
8044
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableFieldHead, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7863
8045
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AITableFieldHead, isStandalone: true, selector: "ai-table-field-head", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
@@ -7870,6 +8052,7 @@ class AITableFieldHead {
7870
8052
  <ai-table-icon [config]="moreIconConfig()"></ai-table-icon>
7871
8053
  }
7872
8054
  </ko-group>
8055
+ <ko-line [config]="fieldOpacityLineConfig()"></ko-line>
7873
8056
  </ko-group>
7874
8057
  `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: KoShape, selector: "ko-shape, ko-circle, ko-label, ko-rect, ko-ellipse, ko-wedge, ko-line, ko-sprite, ko-image, ko-text, ko-text-path, ko-star, ko-ring, ko-arc, ko-tag, ko-path, ko-regular-polygon, ko-arrow, ko-transformer", inputs: ["config"], outputs: ["koMouseover", "koMousemove", "koMouseout", "koMouseenter", "koMouseleave", "koMousedown", "koMouseup", "koWheel", "koContextmenu", "koClick", "koDblclick", "koTouchstart", "koTouchmove", "koTouchend", "koTap", "koDbltap", "koDragstart", "koDragmove", "koDragend"] }, { kind: "component", type: AITableFieldIcon, selector: "ai-table-field-icon", inputs: ["config"] }, { kind: "component", type: AITableText, selector: "ai-table-text", inputs: ["config"], outputs: ["koClick", "koMouseMove"] }, { kind: "component", type: AITableIcon, selector: "ai-table-icon", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7875
8058
  }
@@ -7887,6 +8070,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
7887
8070
  <ai-table-icon [config]="moreIconConfig()"></ai-table-icon>
7888
8071
  }
7889
8072
  </ko-group>
8073
+ <ko-line [config]="fieldOpacityLineConfig()"></ko-line>
7890
8074
  </ko-group>
7891
8075
  `,
7892
8076
  standalone: true,
@@ -7944,7 +8128,8 @@ const createColumnHeads = (config) => {
7944
8128
  };
7945
8129
  };
7946
8130
  const fieldHeads = [];
7947
- const fieldMenus = config.aiTable.context?.aiFieldConfig()?.fieldMenus || [];
8131
+ const fieldMenuFn = config.aiTable.context?.aiFieldConfig()?.fieldMenus;
8132
+ const fieldMenus = (fieldMenuFn && fieldMenuFn(aiTable)) || [];
7948
8133
  let noMoreIcon = false;
7949
8134
  if (fieldMenus.length === 0) {
7950
8135
  noMoreIcon = true;
@@ -8386,7 +8571,6 @@ const createActiveCellBorder = (config) => {
8386
8571
  columnIndex,
8387
8572
  columnCount: totalColumnCount
8388
8573
  });
8389
- // active 外边界和非 active 外边界 box 大小保持一致
8390
8574
  const currentConfig = {
8391
8575
  x: x + offset + AI_TABLE_OFFSET,
8392
8576
  y: y + AI_TABLE_OFFSET,
@@ -8691,31 +8875,29 @@ class AITableDragComponent {
8691
8875
  this.draggedData = null;
8692
8876
  this.mouseStartPosition = null;
8693
8877
  this.aiTableDrag = null;
8694
- effect(() => {
8695
- const drag = this.aiTableGridSelectionService.aiTable.dragState?.();
8696
- if (drag && drag.sourceIds.size > 0) {
8697
- if (!this.rect || !this.line) {
8698
- return;
8699
- }
8700
- this.aiTableDrag = drag;
8701
- }
8702
- else {
8703
- this.aiTableDrag = null;
8704
- }
8705
- });
8878
+ effect(() => this.handleDragStateChange());
8706
8879
  }
8707
8880
  ngOnInit() {
8881
+ this.initElements();
8882
+ this.setupEventListeners();
8883
+ }
8884
+ initElements() {
8708
8885
  this.rect = this.elementRef.nativeElement.querySelector('.rect');
8709
- this.line = this.elementRef.nativeElement.querySelector('.line');
8886
+ this.auxiliaryLine = this.elementRef.nativeElement.querySelector('.auxiliary-line');
8887
+ this.colResizeLine = this.elementRef.nativeElement.querySelector('.col-resize-line');
8888
+ }
8889
+ setupEventListeners() {
8710
8890
  this.mousedownListener = this.render2.listen('window', 'mousedown', (e) => {
8711
8891
  this.mouseStartPosition = { x: e.x, y: e.y };
8892
+ e.preventDefault();
8712
8893
  });
8713
8894
  this.mousemoveListener = this.render2.listen('window', 'mousemove', (e) => {
8895
+ e.preventDefault();
8714
8896
  if (this.timer) {
8715
8897
  cancelAnimationFrame(this.timer);
8716
8898
  }
8717
8899
  this.timer = requestAnimationFrame(() => {
8718
- if (this.mouseStartPosition && this.aiTableDrag) {
8900
+ if (this.aiTableDrag && this.mouseStartPosition) {
8719
8901
  this.handleDrag(e, this.aiTableDrag);
8720
8902
  }
8721
8903
  });
@@ -8726,86 +8908,184 @@ class AITableDragComponent {
8726
8908
  this.handleDragEnd();
8727
8909
  });
8728
8910
  }
8729
- handleDrag(e, drag) {
8730
- if (drag.type !== DragType.none) {
8731
- this.render2.setStyle(this.elementRef.nativeElement, 'display', 'block');
8911
+ handleDragStateChange() {
8912
+ const drag = this.aiTableGridSelectionService.aiTable.dragState?.();
8913
+ if (!drag) {
8914
+ this.aiTableDrag = null;
8915
+ return;
8732
8916
  }
8733
- else {
8917
+ if (drag.type === DragType.none || !this.rect || !this.auxiliaryLine) {
8734
8918
  return;
8735
8919
  }
8736
- const moveX = e.x - this.mouseStartPosition.x;
8737
- const aiTable = this.aiTableGridSelectionService.aiTable;
8738
- const scroll = drag.scroll || { x: 0, y: 0 };
8739
- const coordinate = drag.coordinate;
8920
+ if (drag.type === DragType.columnWidth) {
8921
+ this.setDisplayStyle('block');
8922
+ this.showColResize(drag);
8923
+ }
8924
+ this.aiTableDrag = drag;
8925
+ }
8926
+ handleDrag(e, drag) {
8927
+ if (drag.type === DragType.none) {
8928
+ return;
8929
+ }
8930
+ this.setDisplayStyle('block');
8931
+ const moveX = e.x - (this.mouseStartPosition?.x || 0);
8740
8932
  switch (drag.type) {
8741
8933
  case DragType.field:
8742
- const fields = aiTable.gridData().fields;
8743
- let width = 0;
8744
- fields.forEach((field, index) => {
8745
- if (drag.sourceIds.has(field._id)) {
8746
- width += coordinate.columnIndicesSizeMap[index] || 0;
8747
- }
8748
- });
8749
- const visibleColumnIndexMap = aiTable.context.visibleColumnsIndexMap();
8750
- const sourceColumnIndex = visibleColumnIndexMap.get(drag.sourceIds.values().next().value) || 0;
8751
- const sourceColumnStartX = coordinate.getColumnOffset(sourceColumnIndex);
8752
- const sourceColumnWidth = coordinate.getColumnWidth(sourceColumnIndex);
8753
- // TODO: 目前默认第一列为冻结列,后期支持设置冻结列需要处理
8754
- const isSourceColumnFrozen = sourceColumnIndex === 0;
8755
- const pointerX = moveX + sourceColumnStartX;
8756
- // 拖拽中心点
8757
- const dragCenter = sourceColumnWidth / 2;
8758
- let targetColumnIndex = coordinate.getColumnStartIndex(pointerX + (isSourceColumnFrozen ? scroll.x : 0) + dragCenter);
8759
- let targetColumnStartX = coordinate.getColumnOffset(targetColumnIndex);
8760
- this.render2.setStyle(this.rect, 'cursor', 'move');
8761
- this.render2.setStyle(this.rect, 'width', `${width}px`);
8762
- this.render2.setStyle(this.rect, 'height', `100%`);
8763
- this.render2.setStyle(this.rect, 'top', 0);
8764
- this.render2.setStyle(this.rect, 'left', `${pointerX - (isSourceColumnFrozen ? 0 : scroll.x)}px`);
8765
- const lastColumnOffset = coordinate.getColumnOffset(coordinate.columnCount - 1);
8766
- const lastColumnWidth = coordinate.getColumnWidth(coordinate.columnCount - 1);
8767
- let isLastColumn = false;
8768
- // 处理最后一列
8769
- if (pointerX + dragCenter > lastColumnOffset + lastColumnWidth) {
8770
- targetColumnIndex = coordinate.columnCount;
8771
- targetColumnStartX = lastColumnOffset + lastColumnWidth;
8772
- isLastColumn = true;
8773
- }
8774
- if ((targetColumnIndex >= 0 && (targetColumnIndex - sourceColumnIndex > 1 || targetColumnIndex - sourceColumnIndex < 0)) ||
8775
- isLastColumn) {
8776
- this.render2.setStyle(this.line, 'width', `2px`);
8777
- this.render2.setStyle(this.line, 'height', `100%`);
8778
- this.render2.setStyle(this.line, 'top', 0);
8779
- this.render2.setStyle(this.line, 'left', `${targetColumnStartX - scroll.x}px`);
8780
- const fieldsIndex = [];
8781
- drag.sourceIds.forEach((id) => {
8782
- const index = visibleColumnIndexMap.get(id) || 0;
8783
- fieldsIndex.push(index);
8784
- });
8785
- // 向右移动目标在目标列的前一列
8786
- if (targetColumnIndex > sourceColumnIndex) {
8787
- targetColumnIndex -= 1;
8788
- }
8789
- this.draggedData = { type: DragType.field, targetIndex: targetColumnIndex, fieldIds: drag.sourceIds, fieldsIndex };
8790
- }
8791
- else {
8792
- this.render2.setStyle(this.line, 'width', 0);
8793
- this.draggedData = null;
8794
- }
8934
+ this.movingColumn(drag, moveX);
8795
8935
  break;
8796
8936
  case DragType.record:
8797
8937
  break;
8798
8938
  case DragType.columnWidth:
8939
+ this.movingColumnWidth(drag, moveX);
8799
8940
  break;
8800
8941
  }
8801
8942
  }
8943
+ movingColumn(drag, moveX) {
8944
+ const aiTable = this.aiTableGridSelectionService.aiTable;
8945
+ const scroll = drag.scroll || { x: 0, y: 0 };
8946
+ const coordinate = drag.coordinate;
8947
+ const fields = aiTable.gridData().fields;
8948
+ const width = this.calculateDragWidth(fields, coordinate, drag);
8949
+ const visibleColumnIndexMap = aiTable.context.visibleColumnsIndexMap();
8950
+ const sourceColumnIndex = visibleColumnIndexMap.get(drag.sourceIds.values().next().value) || 0;
8951
+ const sourceColumnStartX = coordinate.getColumnOffset(sourceColumnIndex);
8952
+ const sourceColumnWidth = coordinate.getColumnWidth(sourceColumnIndex);
8953
+ // TODO: 目前默认第一列为冻结列,后期支持设置冻结列需要处理
8954
+ const isSourceColumnFrozen = sourceColumnIndex === 0;
8955
+ const pointerX = moveX + sourceColumnStartX;
8956
+ // 拖拽中心点
8957
+ const dragCenter = sourceColumnWidth / 2;
8958
+ this.setRectStyles({
8959
+ cursor: 'move',
8960
+ width: `${width}px`,
8961
+ height: '100%',
8962
+ top: '0',
8963
+ left: `${pointerX - (isSourceColumnFrozen ? 0 : scroll.x)}px`
8964
+ });
8965
+ const lastColumnOffset = coordinate.getColumnOffset(coordinate.columnCount - 1);
8966
+ const lastColumnWidth = coordinate.getColumnWidth(coordinate.columnCount - 1);
8967
+ let targetColumnIndex = coordinate.getColumnStartIndex(pointerX + (isSourceColumnFrozen ? scroll.x : 0) + dragCenter);
8968
+ let targetColumnStartX = coordinate.getColumnOffset(targetColumnIndex);
8969
+ let isLastColumn = false;
8970
+ // 处理最后一列
8971
+ if (pointerX + dragCenter > lastColumnOffset + lastColumnWidth) {
8972
+ targetColumnIndex = coordinate.columnCount;
8973
+ targetColumnStartX = lastColumnOffset + lastColumnWidth;
8974
+ isLastColumn = true;
8975
+ }
8976
+ if ((targetColumnIndex >= 0 && (targetColumnIndex - sourceColumnIndex > 1 || targetColumnIndex - sourceColumnIndex < 0)) ||
8977
+ isLastColumn) {
8978
+ this.setAuxiliaryLineStyles({
8979
+ width: '2px',
8980
+ height: '100%',
8981
+ top: 0,
8982
+ left: `${targetColumnStartX - scroll.x}px`
8983
+ });
8984
+ const fieldsIndex = [];
8985
+ drag.sourceIds.forEach((id) => {
8986
+ const index = visibleColumnIndexMap.get(id) || 0;
8987
+ fieldsIndex.push(index);
8988
+ });
8989
+ // 向右移动目标在目标列的前一列
8990
+ if (targetColumnIndex > sourceColumnIndex) {
8991
+ targetColumnIndex -= 1;
8992
+ }
8993
+ this.draggedData = { type: DragType.field, targetIndex: targetColumnIndex, fieldIds: drag.sourceIds, fieldsIndex };
8994
+ }
8995
+ else {
8996
+ this.resetAuxiliaryLine();
8997
+ this.draggedData = null;
8998
+ }
8999
+ }
9000
+ movingColumnWidth(drag, moveX) {
9001
+ const aiTable = this.aiTableGridSelectionService.aiTable;
9002
+ const visibleColumnIndexMap = aiTable.context.visibleColumnsIndexMap();
9003
+ const sourceColumnIndex = visibleColumnIndexMap.get(drag.sourceIds.values().next().value) || 0;
9004
+ const sourceColumnStartX = drag.coordinate.getColumnOffset(sourceColumnIndex);
9005
+ const sourceColumnWidth = drag.coordinate.getColumnWidth(sourceColumnIndex);
9006
+ const scroll = drag.scroll || { x: 0, y: 0 };
9007
+ const pointerX = moveX + sourceColumnStartX;
9008
+ const colResizeX = pointerX - (sourceColumnIndex === 0 ? 0 : scroll.x);
9009
+ const left = `${colResizeX + sourceColumnWidth}px`;
9010
+ this.setAuxiliaryLineStyles({
9011
+ width: '2px',
9012
+ height: '100%',
9013
+ top: '0',
9014
+ left
9015
+ });
9016
+ this.draggedData = {
9017
+ type: DragType.columnWidth,
9018
+ fieldIds: drag.sourceIds,
9019
+ width: Math.max(MIN_COLUMN_WIDTH, sourceColumnWidth + moveX)
9020
+ };
9021
+ }
9022
+ showColResize(drag) {
9023
+ const aiTable = this.aiTableGridSelectionService.aiTable;
9024
+ const visibleColumnIndexMap = aiTable.context.visibleColumnsIndexMap();
9025
+ const sourceColumnIndex = visibleColumnIndexMap.get(drag.sourceIds.values().next().value) || 0;
9026
+ const coordinate = drag.coordinate;
9027
+ const sourceColumnStartX = coordinate.getColumnOffset(sourceColumnIndex);
9028
+ const scroll = drag.scroll || { x: 0, y: 0 };
9029
+ let targetColumnIndex = coordinate.getColumnStartIndex(sourceColumnStartX + scroll.x);
9030
+ let targetColumnStartX = coordinate.getColumnOffset(targetColumnIndex);
9031
+ const sourceColumnWidth = drag.coordinate.getColumnWidth(sourceColumnIndex);
9032
+ const opacityLineWidth = 4;
9033
+ // 重置样式
9034
+ this.setRectStyles({ width: 0 });
9035
+ this.resetAuxiliaryLine();
9036
+ this.setDisplayStyle('block');
9037
+ this.render2.setStyle(this.elementRef.nativeElement, 'cursor', 'col-resize');
9038
+ // 隐藏列宽调整线,用于监听鼠标离开此区域后结束宽度调整
9039
+ this.setColResizeLine({
9040
+ opacity: 0,
9041
+ height: '100%',
9042
+ width: `${opacityLineWidth}px`,
9043
+ left: `${targetColumnStartX + sourceColumnWidth - opacityLineWidth / 2}px`,
9044
+ zIndex: 10
9045
+ });
9046
+ this.lineMouseLeaveListener = this.render2.listen(this.colResizeLine, 'mouseleave', () => {
9047
+ this.setDisplayStyle('none');
9048
+ this.lineMouseLeaveListener?.();
9049
+ this.lineMouseLeaveListener = undefined;
9050
+ });
9051
+ }
8802
9052
  handleDragEnd() {
8803
- this.render2.setStyle(this.elementRef.nativeElement, 'display', 'none');
9053
+ this.setDisplayStyle('none');
8804
9054
  if (this.draggedData) {
8805
9055
  this.dragEnd.emit({ ...this.draggedData });
8806
9056
  this.draggedData = null;
8807
9057
  }
8808
9058
  }
9059
+ calculateDragWidth(fields, coordinate, drag) {
9060
+ let width = 0;
9061
+ fields.forEach((field, index) => {
9062
+ if (drag.sourceIds.has(field._id)) {
9063
+ width += coordinate.columnIndicesSizeMap[index] || 0;
9064
+ }
9065
+ });
9066
+ return width;
9067
+ }
9068
+ setDisplayStyle(display) {
9069
+ this.render2.setStyle(this.elementRef.nativeElement, 'display', display);
9070
+ }
9071
+ setRectStyles(styles) {
9072
+ Object.entries(styles).forEach(([prop, value]) => {
9073
+ this.render2.setStyle(this.rect, prop, value);
9074
+ });
9075
+ }
9076
+ setAuxiliaryLineStyles(styles) {
9077
+ Object.entries(styles).forEach(([prop, value]) => {
9078
+ this.render2.setStyle(this.auxiliaryLine, prop, value);
9079
+ });
9080
+ }
9081
+ setColResizeLine(styles) {
9082
+ Object.entries(styles).forEach(([prop, value]) => {
9083
+ this.render2.setStyle(this.colResizeLine, prop, value);
9084
+ });
9085
+ }
9086
+ resetAuxiliaryLine() {
9087
+ this.setAuxiliaryLineStyles({ width: 0 });
9088
+ }
8809
9089
  ngOnDestroy() {
8810
9090
  if (this.mousedownListener)
8811
9091
  this.mousedownListener();
@@ -8813,19 +9093,21 @@ class AITableDragComponent {
8813
9093
  this.mousemoveListener();
8814
9094
  if (this.mouseupListener)
8815
9095
  this.mouseupListener();
9096
+ if (this.lineMouseLeaveListener)
9097
+ this.lineMouseLeaveListener();
8816
9098
  if (this.timer) {
8817
9099
  cancelAnimationFrame(this.timer);
8818
9100
  this.timer = null;
8819
9101
  }
8820
9102
  }
8821
9103
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDragComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8822
- 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 }); }
9104
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AITableDragComponent, isStandalone: true, selector: "ai-table-drag", outputs: { dragEnd: "dragEnd" }, host: { classAttribute: "drag-container" }, ngImport: i0, template: "<div class=\"rect\"></div>\n<div class=\"auxiliary-line\"></div>\n<div class=\"col-resize-line\"></div>", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8823
9105
  }
8824
9106
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AITableDragComponent, decorators: [{
8825
9107
  type: Component,
8826
9108
  args: [{ selector: 'ai-table-drag', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
8827
9109
  class: 'drag-container'
8828
- }, template: "<div class=\"rect\"></div>\n<div class=\"line\"></div>" }]
9110
+ }, template: "<div class=\"rect\"></div>\n<div class=\"auxiliary-line\"></div>\n<div class=\"col-resize-line\"></div>" }]
8829
9111
  }], ctorParameters: () => [] });
8830
9112
 
8831
9113
  class AITableGrid extends AITableGridBase {
@@ -8867,7 +9149,7 @@ class AITableGrid extends AITableGridBase {
8867
9149
  rowInitSize: AI_TABLE_FIELD_HEAD_HEIGHT,
8868
9150
  columnInitSize: AI_TABLE_ROW_HEAD_WIDTH,
8869
9151
  rowIndicesSizeMap: {},
8870
- columnIndicesSizeMap: getColumnIndicesSizeMap(fields),
9152
+ columnIndicesSizeMap: getColumnIndicesSizeMap(this.aiTable, fields),
8871
9153
  frozenColumnCount: this.frozenColumnCount()
8872
9154
  });
8873
9155
  return {
@@ -9009,7 +9291,7 @@ class AITableGrid extends AITableGridBase {
9009
9291
  return;
9010
9292
  const { context } = this.aiTable;
9011
9293
  const { x, y } = pos;
9012
- const curMousePosition = getMousePosition(x, y, this.coordinate(), AITable.getVisibleFields(this.aiTable), context, targetName);
9294
+ const curMousePosition = getMousePosition(this.aiTable, x, y, this.coordinate(), AITable.getVisibleFields(this.aiTable), context, targetName);
9013
9295
  handleMouseStyle(curMousePosition.realTargetName, curMousePosition.areaType, this.containerElement());
9014
9296
  context.setPointPosition(curMousePosition);
9015
9297
  this.timer = null;
@@ -9023,6 +9305,18 @@ class AITableGrid extends AITableGridBase {
9023
9305
  }
9024
9306
  }
9025
9307
  }
9308
+ const { targetName: _targetName, fieldId } = getDetailByTargetName(targetName);
9309
+ if (_targetName === AI_TABLE_FIELD_HEAD_OPACITY_LINE && fieldId) {
9310
+ this.aiTableGridSelectionService.drag({
9311
+ type: DragType.columnWidth,
9312
+ sourceIds: new Set([fieldId]),
9313
+ scroll: this.getScrollPosition(),
9314
+ coordinate: this.coordinate()
9315
+ });
9316
+ }
9317
+ else if (this.aiTableGridSelectionService.getDragStateType() === DragType.columnWidth) {
9318
+ this.aiTableGridSelectionService.clearDrag();
9319
+ }
9026
9320
  });
9027
9321
  }
9028
9322
  stageMousedown(e) {
@@ -9077,7 +9371,10 @@ class AITableGrid extends AITableGridBase {
9077
9371
  x: mouseEvent.x,
9078
9372
  y: mouseEvent.y
9079
9373
  };
9080
- const menuItems = this.aiContextMenuItems();
9374
+ const menuItems = [];
9375
+ if (this.aiContextMenuItems()) {
9376
+ menuItems.push(...this.aiContextMenuItems()(this.aiTable));
9377
+ }
9081
9378
  if (!menuItems.length || menuItems.every((item) => !!(item.hidden && item.hidden(this.aiTable, targetName, position)))) {
9082
9379
  return;
9083
9380
  }
@@ -9306,18 +9603,27 @@ class AITableGrid extends AITableGridBase {
9306
9603
  fromEvent(document, 'keydown')
9307
9604
  .pipe(filter((event) => (event.ctrlKey || event.metaKey) && (event.key === 'c' || event.key === 'v')), takeUntilDestroyed(this.destroyRef))
9308
9605
  .subscribe(async (event) => {
9606
+ if (this.aiReadonly()) {
9607
+ return;
9608
+ }
9609
+ const hasSelectedCells = this.aiTable.selection().selectedCells.size > 0;
9610
+ if (!hasSelectedCells) {
9611
+ return;
9612
+ }
9613
+ const hasEditingCell = !!this.aiTableGridEventService.getCurrentEditCell();
9309
9614
  if (event.key === 'c') {
9310
9615
  const clipboardData = buildClipboardData(this.aiTable);
9311
9616
  if (clipboardData) {
9312
9617
  writeToClipboard(clipboardData).then(() => {
9313
9618
  const copiedCellsCount = this.aiTable.selection().selectedCells.size;
9314
- this.notifyService.success(`已复制 ${copiedCellsCount} 个单元格`, undefined, {
9619
+ const message = getI18nTextByKey(this.aiTable, AITableGridI18nKey.copiedCells).replace('{count}', copiedCellsCount.toString());
9620
+ this.notifyService.success(message, undefined, {
9315
9621
  placement: 'bottomLeft'
9316
9622
  });
9317
9623
  });
9318
9624
  }
9319
9625
  }
9320
- else if (event.key === 'v') {
9626
+ else if (event.key === 'v' && !hasEditingCell) {
9321
9627
  event.preventDefault();
9322
9628
  const actions = {
9323
9629
  updateFieldValue: (data) => {
@@ -9335,7 +9641,7 @@ class AITableGrid extends AITableGridBase {
9335
9641
  };
9336
9642
  writeToAITable(this.aiTable, actions).then((isPasteSuccess) => {
9337
9643
  if (!isPasteSuccess) {
9338
- this.notifyService.error('粘贴内容不符合当前类型', undefined, {
9644
+ this.notifyService.error(getI18nTextByKey(this.aiTable, AITableGridI18nKey.invalidPasteContent), undefined, {
9339
9645
  placement: 'bottomLeft'
9340
9646
  });
9341
9647
  }
@@ -9373,6 +9679,13 @@ class AITableGrid extends AITableGridBase {
9373
9679
  }
9374
9680
  break;
9375
9681
  case DragType.columnWidth:
9682
+ if (data.fieldIds && isNumber(data.width)) {
9683
+ const fieldId = data.fieldIds.values().next().value;
9684
+ this.aiSetFieldWidth.emit({
9685
+ path: [fieldId],
9686
+ width: data.width
9687
+ });
9688
+ }
9376
9689
  break;
9377
9690
  case DragType.record:
9378
9691
  return;
@@ -9393,5 +9706,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
9393
9706
  * Generated bundle index. Do not edit.
9394
9707
  */
9395
9708
 
9396
- export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsSameOptionPipe, AITableFieldSetting, AITableFieldType, AITableFilterOperation, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridSelectionService, AITableMemberType, AITableMouseDownType, AITableQueries, AITableRenderer, AITableRowColumnType, AITableRowType, AITableSelectAllState, AITableSelectOptionStyle, AITableStatType, AI_TABLE_ACTION_COMMON_RADIUS, AI_TABLE_ACTION_COMMON_RIGHT_PADDING, AI_TABLE_ACTION_COMMON_SIZE, AI_TABLE_BLANK, AI_TABLE_CELL, AI_TABLE_CELL_ACTIVE_BORDER_WIDTH, AI_TABLE_CELL_ADD_ITEM_BUTTON_SIZE, AI_TABLE_CELL_ATTACHMENT_ADD, AI_TABLE_CELL_ATTACHMENT_FILE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, AI_TABLE_CELL_FIELD_ITEM_HEIGHT, AI_TABLE_CELL_MAX_ROW_COUNT, AI_TABLE_CELL_MEMBER_ITEM_HEIGHT, AI_TABLE_CELL_MEMBER_ITEM_PADDING, AI_TABLE_CELL_MEMBER_MAX_HEIGHT, AI_TABLE_CELL_MULTI_DOT_RADIUS, AI_TABLE_CELL_MULTI_ITEM_MARGIN_LEFT, AI_TABLE_CELL_MULTI_ITEM_MARGIN_TOP, AI_TABLE_CELL_MULTI_ITEM_MIN_WIDTH, AI_TABLE_CELL_MULTI_PADDING_LEFT, AI_TABLE_CELL_MULTI_PADDING_TOP, AI_TABLE_CELL_PADDING, AI_TABLE_COMMON_FONT_SIZE, AI_TABLE_DEFAULT_COLUMN_WIDTH, AI_TABLE_DOT_RADIUS, AI_TABLE_FIELD_ADD_BUTTON, AI_TABLE_FIELD_ADD_BUTTON_WIDTH, AI_TABLE_FIELD_HEAD, AI_TABLE_FIELD_HEAD_HEIGHT, AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE, AI_TABLE_FIELD_HEAD_MORE, AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX, AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH, AI_TABLE_FIELD_ITEM_MARGIN_RIGHT, AI_TABLE_FIELD_MAX_WIDTH, AI_TABLE_FIELD_MIDDLE_WIDTH, AI_TABLE_FIELD_MINI_WIDTH, AI_TABLE_FIELD_MIN_WIDTH, AI_TABLE_FILE_ICON_ITEM_HEIGHT, AI_TABLE_FILE_ICON_SIZE, AI_TABLE_GRID_FIELD_SERVICE_MAP, AI_TABLE_ICON_COMMON_SIZE, AI_TABLE_MEMBER_AVATAR_SIZE, AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT, AI_TABLE_MEMBER_ITEM_PADDING_RIGHT, AI_TABLE_MIN_TEXT_WIDTH, AI_TABLE_OFFSET, AI_TABLE_OPTION_ITEM_FONT_SIZE, AI_TABLE_OPTION_ITEM_HEIGHT, AI_TABLE_OPTION_ITEM_PADDING, AI_TABLE_OPTION_ITEM_RADIUS, AI_TABLE_PIECE_RADIUS, AI_TABLE_PIECE_WIDTH, AI_TABLE_POPOVER_LEFT_OFFSET, AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS, AI_TABLE_PROGRESS_BAR_HEIGHT, AI_TABLE_PROGRESS_BAR_RADIUS, AI_TABLE_PROGRESS_TEXT_Width, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_HEIGHT, AI_TABLE_ROW_SELECT_CHECKBOX, AI_TABLE_SCROLL_BAR_PADDING, AI_TABLE_TAG_FONT_SIZE, AI_TABLE_TAG_PADDING, AI_TABLE_TEXT_GAP, AbstractEditCellEditor, AddOutlinedPath, AttachmentPath, Check, Colors, ColumnCalendarFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnSelectFilledPath, ColumnTextFilledPath, Coordinate, DBL_CLICK_EDIT_TYPE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_STYLE, DEFAULT_FONT_WEIGHT, DEFAULT_ICON_SHAPE, DEFAULT_ICON_SIZE, DEFAULT_POINT_POSITION, DEFAULT_SCROLL_STATE, DEFAULT_TEXT_ALIGN_CENTER, DEFAULT_TEXT_ALIGN_LEFT, DEFAULT_TEXT_ALIGN_RIGHT, DEFAULT_TEXT_DECORATION, DEFAULT_TEXT_ELLIPSIS, DEFAULT_TEXT_FILL, DEFAULT_TEXT_LINE_HEIGHT, DEFAULT_TEXT_LISTENING, DEFAULT_TEXT_MAX_CACHE, DEFAULT_TEXT_MAX_HEIGHT, DEFAULT_TEXT_SCALE, DEFAULT_TEXT_TRANSFORMS_ENABLED, DEFAULT_TEXT_VERTICAL_ALIGN_MIDDLE, DEFAULT_TEXT_VERTICAL_ALIGN_TOP, DEFAULT_TEXT_WRAP, DEFAULT_WRAP_TEXT_MAX_ROW, DateCellEditorComponent, DepartmentOutlinedPath, Direction, DragType, FONT_SIZE_SM, FieldModelMap, FieldOptions, GRID_CELL_EDITOR_MAP, IsSelectRecordPipe, LinkCellEditorComponent, MIN_COLUMN_WIDTH, MOUSEOVER_EDIT_TYPE, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, ProgressEditorComponent, RatingCellEditorComponent, RendererContext, RowHeight, SelectCellEditorComponent, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextMeasure, Unchecked, UserPipe, WebOutlinedPath, aiTableFragmentAttribute, buildClipboardData, buildGridData, buildGridLinearRows, castToString, compareNumber, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, extractLinkHref, extractText, generateTargetName, getAvatarBgColor, getAvatarShortName, getCellEditorBorderSpace, getCellHorizontalPosition, getColumnIndicesSizeMap, getDefaultFieldValue, getDetailByTargetName, getEditorBoxOffset, getEditorSpace, getFieldOptionByField, getFieldValue, getHoverCell, getHoverEditorBoxOffset, getHoverEditorSpace, getMousePosition, getPlaceHolderCellsConfigs, getSystemFieldValue, getTargetName, getTextWidth, getVisibleRangeInfo, handleMouseStyle, hasIntersect, idCreator, idsCreator, imageCache, isArrayField, isCellMatchKeywords, isClipboardReadSupported, isClipboardReadTextSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isEmpty, isMac, isNumberFiled, isSameFieldOption, isSelectedField, isSystemField, isWindows, isWindowsOS, isWithinFrozenColumnBoundary, readFromClipboard, scrollMax, setMouseStyle, shortIdCreator, shortIdsCreator, stringInclude, textDataCache, transformCellValue, writeToAITable, writeToClipboard, zhIntlCollator };
9709
+ export { AITable, AITableAreaType, AITableAvatarSize, AITableAvatarType, AITableCheckType, AITableContextMenu, AITableDomGrid, AITableFieldIsSameOptionPipe, AITableFieldSetting, AITableFieldType, AITableFilterOperation, AITableGrid, AITableGridEventService, AITableGridFieldService, AITableGridI18nKey, AITableGridSelectionService, AITableMemberType, AITableMouseDownType, AITableQueries, AITableRenderer, AITableRowColumnType, AITableRowType, AITableSelectAllState, AITableSelectOptionStyle, AITableStatType, AI_TABLE_ACTION_COMMON_RADIUS, AI_TABLE_ACTION_COMMON_RIGHT_PADDING, AI_TABLE_ACTION_COMMON_SIZE, AI_TABLE_BLANK, AI_TABLE_CELL, AI_TABLE_CELL_ACTIVE_BORDER_WIDTH, AI_TABLE_CELL_ADD_ITEM_BUTTON_SIZE, AI_TABLE_CELL_ATTACHMENT_ADD, AI_TABLE_CELL_ATTACHMENT_FILE, AI_TABLE_CELL_BORDER, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE, AI_TABLE_CELL_DELETE_ITEM_BUTTON_SIZE_OFFSET, AI_TABLE_CELL_EMOJI_PADDING, AI_TABLE_CELL_EMOJI_SIZE, AI_TABLE_CELL_FIELD_ITEM_HEIGHT, AI_TABLE_CELL_MAX_ROW_COUNT, AI_TABLE_CELL_MEMBER_ITEM_HEIGHT, AI_TABLE_CELL_MEMBER_ITEM_PADDING, AI_TABLE_CELL_MEMBER_MAX_HEIGHT, AI_TABLE_CELL_MULTI_DOT_RADIUS, AI_TABLE_CELL_MULTI_ITEM_MARGIN_LEFT, AI_TABLE_CELL_MULTI_ITEM_MARGIN_TOP, AI_TABLE_CELL_MULTI_ITEM_MIN_WIDTH, AI_TABLE_CELL_MULTI_PADDING_LEFT, AI_TABLE_CELL_MULTI_PADDING_TOP, AI_TABLE_CELL_PADDING, AI_TABLE_COMMON_FONT_SIZE, AI_TABLE_DEFAULT_COLUMN_WIDTH, AI_TABLE_DOT_RADIUS, AI_TABLE_FIELD_ADD_BUTTON, AI_TABLE_FIELD_ADD_BUTTON_WIDTH, AI_TABLE_FIELD_HEAD, AI_TABLE_FIELD_HEAD_HEIGHT, AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE, AI_TABLE_FIELD_HEAD_MORE, AI_TABLE_FIELD_HEAD_OPACITY_LINE, AI_TABLE_FIELD_HEAD_SELECT_CHECKBOX, AI_TABLE_FIELD_HEAD_TEXT_MIN_WIDTH, AI_TABLE_FIELD_ITEM_MARGIN_RIGHT, AI_TABLE_FIELD_MAX_WIDTH, AI_TABLE_FIELD_MIDDLE_WIDTH, AI_TABLE_FIELD_MINI_WIDTH, AI_TABLE_FIELD_MIN_WIDTH, AI_TABLE_FILE_ICON_ITEM_HEIGHT, AI_TABLE_FILE_ICON_SIZE, AI_TABLE_GRID_FIELD_SERVICE_MAP, AI_TABLE_ICON_COMMON_SIZE, AI_TABLE_MEMBER_AVATAR_SIZE, AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT, AI_TABLE_MEMBER_ITEM_PADDING_RIGHT, AI_TABLE_MIN_TEXT_WIDTH, AI_TABLE_OFFSET, AI_TABLE_OPTION_ITEM_FONT_SIZE, AI_TABLE_OPTION_ITEM_HEIGHT, AI_TABLE_OPTION_ITEM_PADDING, AI_TABLE_OPTION_ITEM_RADIUS, AI_TABLE_PIECE_RADIUS, AI_TABLE_PIECE_WIDTH, AI_TABLE_POPOVER_LEFT_OFFSET, AI_TABLE_PREVENT_CLEAR_SELECTION_CLASS, AI_TABLE_PROGRESS_BAR_HEIGHT, AI_TABLE_PROGRESS_BAR_RADIUS, AI_TABLE_PROGRESS_TEXT_Width, AI_TABLE_ROW_ADD_BUTTON, AI_TABLE_ROW_BLANK_HEIGHT, AI_TABLE_ROW_HEAD, AI_TABLE_ROW_HEAD_SIZE, AI_TABLE_ROW_HEAD_WIDTH, AI_TABLE_ROW_HEIGHT, AI_TABLE_ROW_SELECT_CHECKBOX, AI_TABLE_SCROLL_BAR_PADDING, AI_TABLE_TAG_FONT_SIZE, AI_TABLE_TAG_PADDING, AI_TABLE_TEXT_GAP, AbstractEditCellEditor, AddOutlinedPath, AttachmentPath, Check, Colors, ColumnCalendarFilledPath, ColumnLinkOutlinedPath, ColumnMemberFilledPath, ColumnMultipleFillPath, ColumnNumberFilledPath, ColumnProgressFilledPath, ColumnRatingFilledPath, ColumnSelectFilledPath, ColumnTextFilledPath, Coordinate, DBL_CLICK_EDIT_TYPE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_STYLE, DEFAULT_FONT_WEIGHT, DEFAULT_ICON_SHAPE, DEFAULT_ICON_SIZE, DEFAULT_POINT_POSITION, DEFAULT_SCROLL_STATE, DEFAULT_TEXT_ALIGN_CENTER, DEFAULT_TEXT_ALIGN_LEFT, DEFAULT_TEXT_ALIGN_RIGHT, DEFAULT_TEXT_DECORATION, DEFAULT_TEXT_ELLIPSIS, DEFAULT_TEXT_FILL, DEFAULT_TEXT_LINE_HEIGHT, DEFAULT_TEXT_LISTENING, DEFAULT_TEXT_MAX_CACHE, DEFAULT_TEXT_MAX_HEIGHT, DEFAULT_TEXT_SCALE, DEFAULT_TEXT_TRANSFORMS_ENABLED, DEFAULT_TEXT_VERTICAL_ALIGN_MIDDLE, DEFAULT_TEXT_VERTICAL_ALIGN_TOP, DEFAULT_TEXT_WRAP, DEFAULT_WRAP_TEXT_MAX_ROW, DateCellEditorComponent, DepartmentOutlinedPath, Direction, DragType, FONT_SIZE_SM, FieldModelMap, GRID_CELL_EDITOR_MAP, IsSelectRecordPipe, LinkCellEditorComponent, MIN_COLUMN_WIDTH, MOUSEOVER_EDIT_TYPE, MemberSettingPipe, MoreStandOutlinedPath, NumberCellEditorComponent, ProgressEditorComponent, RatingCellEditorComponent, RendererContext, RowHeight, SelectCellEditorComponent, SelectOptionComponent, SelectOptionPipe, SelectOptionsPipe, SelectSettingPipe, StarFill, TextCellEditorComponent, TextMeasure, Unchecked, UserPipe, WebOutlinedPath, aiTableFragmentAttribute, buildClipboardData, buildGridData, buildGridLinearRows, castToString, compareNumber, compareString, createAITable, createActiveCellBorder, createCells, createDefaultField, createDefaultFieldName, 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 };
9397
9710
  //# sourceMappingURL=ai-table-grid.mjs.map