@ai-table/grid 0.4.8 → 0.5.0

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.
@@ -49,6 +49,7 @@
49
49
 
50
50
  .cell-item {
51
51
  .field-action {
52
+ margin-right: -15px;
52
53
  display: none;
53
54
  &.active {
54
55
  display: block;
@@ -24,7 +24,7 @@ import { TextPath } from 'konva/lib/shapes/TextPath';
24
24
  import { Transformer } from 'konva/lib/shapes/Transformer';
25
25
  import { Wedge } from 'konva/lib/shapes/Wedge';
26
26
  import * as i1$1 from 'ngx-tethys/popover';
27
- import { ThyPopoverRef, ThyPopover, ThyPopoverDirective, ThyPopoverModule } from 'ngx-tethys/popover';
27
+ import { ThyPopoverRef, ThyPopover, ThyPopoverModule } from 'ngx-tethys/popover';
28
28
  import { AITableFieldGroup, AITableFieldType, AITableRecordHeightType, DragType, AITableRowColumnType, isUndefinedOrNull, idCreator as idCreator$1, isUrl, isEmpty, AITableFilterOperation, AttachmentFieldBase, AITableStatType, DateFieldBase, DEFAULT_FIELD_STAT_TYPE_ITEMS, isDateValid, isDateAndReturnDate, SelectFieldBase, AITableSelectOptionStyle, generateOptionsByTexts, LinkFieldBase, MemberFieldBase, NumberFieldBase, ProgressFieldBase, isProgressAndReturnValue, RateFieldBase, RichTextFieldBase, TextFieldBase, CheckboxFieldBase, FieldModelBaseMap, numberFormat, DragDirection, AI_TABLE_MIN_FROZEN_COLUMN_COUNT } from '@ai-table/utils';
29
29
  import ObjectID from 'bson-objectid';
30
30
  import { customAlphabet } from 'nanoid';
@@ -5950,6 +5950,7 @@ class Layout extends Drawer {
5950
5950
  this.columnCount = 0;
5951
5951
  this.containerWidth = 0;
5952
5952
  this.frozenColumnCount = 0;
5953
+ this.groupOffset = 0;
5953
5954
  this.rowHeadWidth = AI_TABLE_ROW_HEAD_WIDTH_AND_DRAG_ICON_WIDTH;
5954
5955
  this.hiddenIndexColumn = false;
5955
5956
  this.showExpandIcon = false;
@@ -5958,7 +5959,7 @@ class Layout extends Drawer {
5958
5959
  this.xIsScroll = false;
5959
5960
  }
5960
5961
  // 用于初始化或重置布局的基本属性。这个方法通常在每次渲染新的一行或单元格时调用,确保布局信息是最新的
5961
- init({ x, y, rowIndex, columnIndex, rowHeight, columnWidth, columnCount, containerWidth, rowHeadWidth, hiddenIndexColumn, showExpandIcon, hiddenRowDrag, readonly, frozenColumnCount, xIsScroll }) {
5962
+ init({ x, y, rowIndex, columnIndex, rowHeight, columnWidth, columnCount, containerWidth, rowHeadWidth, hiddenIndexColumn, showExpandIcon, hiddenRowDrag, readonly, frozenColumnCount, xIsScroll, groupOffset }) {
5962
5963
  this.x = x;
5963
5964
  this.y = y;
5964
5965
  this.rowIndex = rowIndex;
@@ -5974,6 +5975,7 @@ class Layout extends Drawer {
5974
5975
  this.readonly = readonly;
5975
5976
  this.frozenColumnCount = frozenColumnCount;
5976
5977
  this.xIsScroll = xIsScroll;
5978
+ this.groupOffset = groupOffset;
5977
5979
  }
5978
5980
  // 当前单元格是否是行的第一列
5979
5981
  get isFirst() {
@@ -6282,7 +6284,7 @@ class MemberLayout extends CellBaseLayout {
6282
6284
  const count = this.items.length - renderItems.length;
6283
6285
  const renderAtoms = [];
6284
6286
  let itemWidth = 2 * AI_TABLE_TAG_PADDING;
6285
- const textAtom = this.getTextAtom(`+${count}`, undefined, FONT_SIZE_SM);
6287
+ const textAtom = this.getTextAtom(`+${count}`, undefined, DEFAULT_FONT_SIZE);
6286
6288
  itemWidth += textAtom.width;
6287
6289
  renderAtoms.push({
6288
6290
  type: AITableRenderAtomType.circle,
@@ -6295,7 +6297,7 @@ class MemberLayout extends CellBaseLayout {
6295
6297
  renderAtoms.push({
6296
6298
  ...textAtom,
6297
6299
  x: lastItem.x + (AITableAvatarSize.size24 - textAtom.width) / 2,
6298
- y: lastItem.y + (AITableAvatarSize.size24 - FONT_SIZE_SM) / 2,
6300
+ y: lastItem.y + (AITableAvatarSize.size24 - DEFAULT_FONT_SIZE) / 2,
6299
6301
  fillStyle: Colors.white
6300
6302
  });
6301
6303
  return [
@@ -6333,12 +6335,12 @@ class MemberLayout extends CellBaseLayout {
6333
6335
  });
6334
6336
  const textX = AITableAvatarSize.size24 + AI_TABLE_MEMBER_ITEM_AVATAR_MARGIN_RIGHT;
6335
6337
  const textWidth = containerMaxWidth - textX;
6336
- const textAtom = this.getTextAtom(display_name || '', textWidth, FONT_SIZE_SM);
6338
+ const textAtom = this.getTextAtom(display_name || '', textWidth, DEFAULT_FONT_SIZE);
6337
6339
  renderAtoms.push({
6338
6340
  ...textAtom,
6339
6341
  type: AITableRenderAtomType.text,
6340
6342
  x: textX,
6341
- y: (AITableAvatarSize.size24 - FONT_SIZE_SM) / 2,
6343
+ y: (AITableAvatarSize.size24 - DEFAULT_FONT_SIZE) / 2,
6342
6344
  width: textWidth
6343
6345
  });
6344
6346
  }
@@ -6832,11 +6834,12 @@ class RecordLayout extends Layout {
6832
6834
  const columnWidth = this.columnWidth;
6833
6835
  const width = this.rowHeadWidth - x + columnWidth;
6834
6836
  const expandWidth = this.showExpandIcon ? AI_TABLE_ROW_HEAD_EXPAND_WIDTH : 0;
6835
- const indexWidth = this.rowHeadWidth - x - expandWidth;
6837
+ const indexWidth = this.rowHeadWidth - x;
6838
+ const groupOffset = this.groupOffset ?? 0;
6836
6839
  this.rect({
6837
- x: x + indexWidth,
6840
+ x: x + indexWidth + groupOffset,
6838
6841
  y: y + AI_TABLE_OFFSET,
6839
- width: width - indexWidth,
6842
+ width: width - indexWidth - groupOffset,
6840
6843
  height: rowHeight - AI_TABLE_OFFSET * 2,
6841
6844
  fill
6842
6845
  });
@@ -6851,7 +6854,7 @@ class RecordLayout extends Layout {
6851
6854
  this.rect({
6852
6855
  x: x,
6853
6856
  y: y + AI_TABLE_OFFSET,
6854
- width: indexWidth,
6857
+ width: indexWidth + groupOffset,
6855
6858
  height: rowHeight - AI_TABLE_OFFSET * 2,
6856
6859
  fill: indexFill
6857
6860
  });
@@ -6859,12 +6862,12 @@ class RecordLayout extends Layout {
6859
6862
  this.line({
6860
6863
  x: x,
6861
6864
  y: y,
6862
- points: [indexWidth, 0, indexWidth, rowHeight],
6865
+ points: [indexWidth - expandWidth, 0, indexWidth - expandWidth, rowHeight],
6863
6866
  stroke: this.colors.gray200
6864
6867
  });
6865
6868
  // 右垂直边框
6866
6869
  this.line({
6867
- x: x + indexWidth + expandWidth + columnWidth + AI_TABLE_OFFSET,
6870
+ x: x + indexWidth + columnWidth + AI_TABLE_OFFSET,
6868
6871
  y: y,
6869
6872
  points: [0, 0, 0, rowHeight],
6870
6873
  stroke: this.colors.gray200
@@ -6873,7 +6876,7 @@ class RecordLayout extends Layout {
6873
6876
  // 设置字体样式,居中绘制行号
6874
6877
  this.setStyle({ fontSize: DEFAULT_FONT_SIZE });
6875
6878
  this.text({
6876
- x: x + indexWidth / 2 - AI_TABLE_CELL_LINE_BORDER,
6879
+ x: x + (indexWidth - expandWidth) / 2 - AI_TABLE_CELL_LINE_BORDER,
6877
6880
  y: y + AI_TABLE_FIELD_HEAD_HEIGHT / 2,
6878
6881
  text: String(row.displayIndex),
6879
6882
  textAlign: DEFAULT_TEXT_ALIGN_CENTER,
@@ -7111,6 +7114,12 @@ const createCells = (config) => {
7111
7114
  const cell = [recordId, fieldId];
7112
7115
  let background = getCellBackground(cell, isHover, targetName, aiTable);
7113
7116
  let indexBackground = getIndexCellBackground(cell, isHover, targetName, aiTable);
7117
+ const { width, offset, isGroupAndFirstColumn } = getCellHorizontalPosition({
7118
+ columnIndex,
7119
+ columnWidth,
7120
+ columnCount,
7121
+ depth
7122
+ });
7114
7123
  recordLayout.init({
7115
7124
  x,
7116
7125
  y,
@@ -7126,7 +7135,8 @@ const createCells = (config) => {
7126
7135
  showExpandIcon,
7127
7136
  readonly: aiTable.context?.readonly?.(),
7128
7137
  frozenColumnCount,
7129
- xIsScroll
7138
+ xIsScroll,
7139
+ groupOffset: columnWidth - width
7130
7140
  });
7131
7141
  recordLayout.render({
7132
7142
  row,
@@ -7135,12 +7145,6 @@ const createCells = (config) => {
7135
7145
  isHoverRow: isHoverRecord(isHover, targetName),
7136
7146
  isCheckedRow: isSelectedRecord(recordId, aiTable)
7137
7147
  });
7138
- const { width, offset, isGroupAndFirstColumn } = getCellHorizontalPosition({
7139
- columnIndex,
7140
- columnWidth,
7141
- columnCount,
7142
- depth
7143
- });
7144
7148
  let realX = x + offset + AI_TABLE_OFFSET;
7145
7149
  if (isGroupAndFirstColumn) {
7146
7150
  realX += AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE;
@@ -7759,6 +7763,7 @@ class AITableFrozenColumnHeads {
7759
7763
  constructor() {
7760
7764
  this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
7761
7765
  this.textMeasure = TextMeasure();
7766
+ this.emptyRecordsSelectAllStatus = signal(AITableSelectAllState.none, ...(ngDevMode ? [{ debugName: "emptyRecordsSelectAllStatus" }] : []));
7762
7767
  this.coordinate = computed(() => {
7763
7768
  const config = this.config();
7764
7769
  if (!config)
@@ -7783,8 +7788,12 @@ class AITableFrozenColumnHeads {
7783
7788
  }, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
7784
7789
  this.isChecked = computed(() => {
7785
7790
  const config = this.config();
7786
- if (!config)
7791
+ if (!config) {
7787
7792
  return false;
7793
+ }
7794
+ if (config.aiTable?.records().length === 0) {
7795
+ return this.emptyRecordsSelectAllStatus() === AITableSelectAllState.all;
7796
+ }
7788
7797
  const selectedRecords = config.aiTable.selection().selectedRecords;
7789
7798
  const selectedAllState = selectedRecords.size === config.aiTable.records().length
7790
7799
  ? AITableSelectAllState.all
@@ -7963,12 +7972,17 @@ class AITableFrozenColumnHeads {
7963
7972
  return lines;
7964
7973
  }, ...(ngDevMode ? [{ debugName: "cellLinesConfig" }] : []));
7965
7974
  }
7975
+ selectAllClick(e) {
7976
+ if (this.config()?.aiTable?.records().length === 0) {
7977
+ this.emptyRecordsSelectAllStatus.set(this.emptyRecordsSelectAllStatus() === AITableSelectAllState.all ? AITableSelectAllState.none : AITableSelectAllState.all);
7978
+ }
7979
+ }
7966
7980
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AITableFrozenColumnHeads, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7967
7981
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: AITableFrozenColumnHeads, isStandalone: true, selector: "ai-table-frozen-column-heads", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
7968
7982
  @if (!hiddenIndexColumn()) {
7969
7983
  <ko-group>
7970
7984
  @if (!readonly()) {
7971
- <ai-table-icon [config]="iconConfig()"></ai-table-icon>
7985
+ <ai-table-icon [config]="iconConfig()" (koClick)="selectAllClick($event)"></ai-table-icon>
7972
7986
  } @else {
7973
7987
  <ai-table-text [config]="textConfig()"></ai-table-text>
7974
7988
  }
@@ -7991,7 +8005,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
7991
8005
  @if (!hiddenIndexColumn()) {
7992
8006
  <ko-group>
7993
8007
  @if (!readonly()) {
7994
- <ai-table-icon [config]="iconConfig()"></ai-table-icon>
8008
+ <ai-table-icon [config]="iconConfig()" (koClick)="selectAllClick($event)"></ai-table-icon>
7995
8009
  } @else {
7996
8010
  <ai-table-text [config]="textConfig()"></ai-table-text>
7997
8011
  }
@@ -8297,6 +8311,98 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
8297
8311
  }]
8298
8312
  }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }] } });
8299
8313
 
8314
+ class AITableExpandRecord {
8315
+ constructor() {
8316
+ this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
8317
+ this.backgroundConfig = computed(() => {
8318
+ const { coordinate, aiTable } = this.config();
8319
+ const context = aiTable.context;
8320
+ const { rowIndex: pointRowIndex, columnIndex } = context.pointPosition();
8321
+ const firstColumnOffset = coordinate.getColumnOffset(0);
8322
+ const y = coordinate.getRowOffset(pointRowIndex) + AI_TABLE_OFFSET;
8323
+ const rowHeight = coordinate.getRowHeight(pointRowIndex);
8324
+ const firstField = aiTable.gridData().fields[0];
8325
+ const row = context.linearRows()[pointRowIndex];
8326
+ const recordId = row?._id;
8327
+ const isRateOrProgress = firstField?.type === AITableFieldType.rate || firstField?.type === AITableFieldType.progress;
8328
+ const isFirstColumn = columnIndex === 0;
8329
+ const activeCell = aiTable.selection()?.activeCell;
8330
+ const fieldId = aiTable.gridData().fields[0]._id;
8331
+ const isWhiteBg = isRateOrProgress && isFirstColumn && (!activeCell || (activeCell?.[0] === recordId && activeCell?.[1] === fieldId));
8332
+ return {
8333
+ coordinate,
8334
+ x: firstColumnOffset - AI_TABLE_ROW_HEAD_EXPAND_WIDTH,
8335
+ y: y,
8336
+ width: AI_TABLE_ROW_HEAD_EXPAND_WIDTH + AI_TABLE_CELL_LINE_BORDER * 2 + AI_TABLE_OFFSET,
8337
+ height: rowHeight,
8338
+ fill: isWhiteBg ? Colors.white : Colors.transparent,
8339
+ hoverFill: Colors.transparent,
8340
+ listening: true
8341
+ };
8342
+ }, ...(ngDevMode ? [{ debugName: "backgroundConfig" }] : []));
8343
+ this.shouldShowIcon = computed(() => {
8344
+ const { aiTable, rowStartIndex, rowStopIndex } = this.config();
8345
+ const context = aiTable.context;
8346
+ if (!context)
8347
+ return false;
8348
+ if (!context.recordDetailConfig?.()?.showExpandIcon)
8349
+ return false;
8350
+ const { rowIndex: pointRowIndex } = context.pointPosition();
8351
+ const row = context.linearRows()[pointRowIndex];
8352
+ return pointRowIndex >= rowStartIndex && pointRowIndex <= rowStopIndex && row && row.type === AITableRowType.record;
8353
+ }, ...(ngDevMode ? [{ debugName: "shouldShowIcon" }] : []));
8354
+ this.expandIconConfig = computed(() => {
8355
+ const { coordinate, aiTable } = this.config();
8356
+ const context = aiTable.context;
8357
+ const { rowIndex: pointRowIndex } = context.pointPosition();
8358
+ const row = context.linearRows()[pointRowIndex];
8359
+ const recordId = row?._id;
8360
+ const firstColumnOffset = coordinate.getColumnOffset(0);
8361
+ const y = coordinate.getRowOffset(pointRowIndex) + AI_TABLE_OFFSET;
8362
+ return {
8363
+ coordinate,
8364
+ name: generateTargetName({
8365
+ targetName: AI_TABLE_EXPAND_RECORD_ICON,
8366
+ recordId,
8367
+ mouseStyle: 'pointer'
8368
+ }),
8369
+ x: firstColumnOffset - AI_TABLE_ROW_HEAD_EXPAND_WIDTH + (AI_TABLE_ROW_HEAD_EXPAND_WIDTH - AI_TABLE_ACTION_COMMON_SIZE) / 2,
8370
+ y: y + (AI_TABLE_FIELD_HEAD_HEIGHT - AI_TABLE_ACTION_COMMON_SIZE) / 2,
8371
+ data: ExpandRecordPath,
8372
+ fill: Colors.gray600,
8373
+ hoverFill: Colors.primary,
8374
+ backgroundWidth: AI_TABLE_ACTION_COMMON_SIZE,
8375
+ backgroundHeight: AI_TABLE_ACTION_COMMON_SIZE,
8376
+ cornerRadius: AI_TABLE_ACTION_COMMON_RADIUS,
8377
+ listening: true
8378
+ };
8379
+ }, ...(ngDevMode ? [{ debugName: "expandIconConfig" }] : []));
8380
+ }
8381
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AITableExpandRecord, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8382
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: AITableExpandRecord, isStandalone: true, selector: "ai-table-expand-record", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
8383
+ <ko-group>
8384
+ @if (shouldShowIcon()) {
8385
+ <ai-table-action-icon [config]="expandIconConfig()"></ai-table-action-icon>
8386
+ }
8387
+ </ko-group>
8388
+ `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: AITableActionIcon, selector: "ai-table-action-icon", inputs: ["config"], outputs: ["onClick", "onMousemove", "onMouseenter", "onMouseleave"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8389
+ }
8390
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AITableExpandRecord, decorators: [{
8391
+ type: Component,
8392
+ args: [{
8393
+ selector: 'ai-table-expand-record',
8394
+ template: `
8395
+ <ko-group>
8396
+ @if (shouldShowIcon()) {
8397
+ <ai-table-action-icon [config]="expandIconConfig()"></ai-table-action-icon>
8398
+ }
8399
+ </ko-group>
8400
+ `,
8401
+ imports: [KoContainer, AITableActionIcon],
8402
+ changeDetection: ChangeDetectionStrategy.OnPush
8403
+ }]
8404
+ }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }] } });
8405
+
8300
8406
  class AITableBackground {
8301
8407
  constructor() {
8302
8408
  this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
@@ -8467,100 +8573,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
8467
8573
  }]
8468
8574
  }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], isActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "isActive", required: false }] }], koClick: [{ type: i0.Output, args: ["koClick"] }], hover: [{ type: i0.Output, args: ["hover"] }], koMouseenter: [{ type: i0.Output, args: ["koMouseenter"] }], koMouseleave: [{ type: i0.Output, args: ["koMouseleave"] }], isHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "isHover", required: false }] }, { type: i0.Output, args: ["isHoverChange"] }] } });
8469
8575
 
8470
- class AITableExpandRecord {
8471
- constructor() {
8472
- this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
8473
- this.backgroundConfig = computed(() => {
8474
- const { coordinate, aiTable } = this.config();
8475
- const context = aiTable.context;
8476
- const { rowIndex: pointRowIndex, columnIndex } = context.pointPosition();
8477
- const firstColumnOffset = coordinate.getColumnOffset(0);
8478
- const y = coordinate.getRowOffset(pointRowIndex) + AI_TABLE_OFFSET;
8479
- const rowHeight = coordinate.getRowHeight(pointRowIndex);
8480
- const firstField = aiTable.gridData().fields[0];
8481
- const row = context.linearRows()[pointRowIndex];
8482
- const recordId = row?._id;
8483
- const isRateOrProgress = firstField?.type === AITableFieldType.rate || firstField?.type === AITableFieldType.progress;
8484
- const isFirstColumn = columnIndex === 0;
8485
- const activeCell = aiTable.selection()?.activeCell;
8486
- const fieldId = aiTable.gridData().fields[0]._id;
8487
- const isWhiteBg = isRateOrProgress && isFirstColumn && (!activeCell || (activeCell?.[0] === recordId && activeCell?.[1] === fieldId));
8488
- return {
8489
- coordinate,
8490
- x: firstColumnOffset - AI_TABLE_ROW_HEAD_EXPAND_WIDTH,
8491
- y: y,
8492
- width: AI_TABLE_ROW_HEAD_EXPAND_WIDTH + AI_TABLE_CELL_LINE_BORDER * 2 + AI_TABLE_OFFSET,
8493
- height: rowHeight,
8494
- fill: isWhiteBg ? Colors.white : Colors.transparent,
8495
- hoverFill: Colors.transparent,
8496
- listening: true
8497
- };
8498
- }, ...(ngDevMode ? [{ debugName: "backgroundConfig" }] : []));
8499
- this.shouldShowIcon = computed(() => {
8500
- const { aiTable, rowStartIndex, rowStopIndex } = this.config();
8501
- const context = aiTable.context;
8502
- if (!context)
8503
- return false;
8504
- if (!context.recordDetailConfig?.()?.showExpandIcon)
8505
- return false;
8506
- const { rowIndex: pointRowIndex } = context.pointPosition();
8507
- const row = context.linearRows()[pointRowIndex];
8508
- return pointRowIndex >= rowStartIndex && pointRowIndex <= rowStopIndex && row && row.type === AITableRowType.record;
8509
- }, ...(ngDevMode ? [{ debugName: "shouldShowIcon" }] : []));
8510
- this.expandIconConfig = computed(() => {
8511
- const { coordinate, aiTable } = this.config();
8512
- const context = aiTable.context;
8513
- const { rowIndex: pointRowIndex } = context.pointPosition();
8514
- const row = context.linearRows()[pointRowIndex];
8515
- const recordId = row?._id;
8516
- const firstColumnOffset = coordinate.getColumnOffset(0);
8517
- const y = coordinate.getRowOffset(pointRowIndex) + AI_TABLE_OFFSET;
8518
- return {
8519
- coordinate,
8520
- name: generateTargetName({
8521
- targetName: AI_TABLE_EXPAND_RECORD_ICON,
8522
- recordId,
8523
- mouseStyle: 'pointer'
8524
- }),
8525
- x: firstColumnOffset - AI_TABLE_ROW_HEAD_EXPAND_WIDTH + (AI_TABLE_ROW_HEAD_EXPAND_WIDTH - AI_TABLE_ACTION_COMMON_SIZE) / 2,
8526
- y: y + (AI_TABLE_FIELD_HEAD_HEIGHT - AI_TABLE_ACTION_COMMON_SIZE) / 2,
8527
- data: ExpandRecordPath,
8528
- fill: Colors.gray600,
8529
- hoverFill: Colors.primary,
8530
- backgroundWidth: AI_TABLE_ACTION_COMMON_SIZE,
8531
- backgroundHeight: AI_TABLE_ACTION_COMMON_SIZE,
8532
- cornerRadius: AI_TABLE_ACTION_COMMON_RADIUS,
8533
- listening: true
8534
- };
8535
- }, ...(ngDevMode ? [{ debugName: "expandIconConfig" }] : []));
8536
- }
8537
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AITableExpandRecord, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8538
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: AITableExpandRecord, isStandalone: true, selector: "ai-table-expand-record", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
8539
- <ko-group>
8540
- @if (shouldShowIcon()) {
8541
- <ai-table-background [config]="backgroundConfig()"></ai-table-background>
8542
- <ai-table-action-icon [config]="expandIconConfig()"></ai-table-action-icon>
8543
- }
8544
- </ko-group>
8545
- `, isInline: true, dependencies: [{ kind: "component", type: KoContainer, selector: "ko-layer, ko-fastlayer, ko-group" }, { kind: "component", type: AITableActionIcon, selector: "ai-table-action-icon", inputs: ["config"], outputs: ["onClick", "onMousemove", "onMouseenter", "onMouseleave"] }, { kind: "component", type: AITableBackground, selector: "ai-table-background", inputs: ["config", "isActive", "isHover"], outputs: ["koClick", "hover", "koMouseenter", "koMouseleave", "isHoverChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8546
- }
8547
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AITableExpandRecord, decorators: [{
8548
- type: Component,
8549
- args: [{
8550
- selector: 'ai-table-expand-record',
8551
- template: `
8552
- <ko-group>
8553
- @if (shouldShowIcon()) {
8554
- <ai-table-background [config]="backgroundConfig()"></ai-table-background>
8555
- <ai-table-action-icon [config]="expandIconConfig()"></ai-table-action-icon>
8556
- }
8557
- </ko-group>
8558
- `,
8559
- imports: [KoContainer, AITableActionIcon, AITableBackground],
8560
- changeDetection: ChangeDetectionStrategy.OnPush
8561
- }]
8562
- }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }] } });
8563
-
8564
8576
  class AITableShadow {
8565
8577
  constructor() {
8566
8578
  this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
@@ -9561,17 +9573,19 @@ class AITableFieldStat {
9561
9573
  statMenus: fieldModel.getStatTypes(aiTable)
9562
9574
  }
9563
9575
  });
9564
- ref.componentInstance.menuClick.subscribe((event) => {
9565
- this.isActive.set(false);
9566
- actions.setFieldStatType({
9567
- path: [field._id],
9568
- statType: event.menu.type
9576
+ if (ref) {
9577
+ ref.componentInstance.menuClick.subscribe((event) => {
9578
+ this.isActive.set(false);
9579
+ actions.setFieldStatType({
9580
+ path: [field._id],
9581
+ statType: event.menu.type
9582
+ });
9569
9583
  });
9570
- });
9571
- ref.afterClosed().subscribe(() => {
9572
- this.isActive.set(false);
9573
- this.hover.emit(false);
9574
- });
9584
+ ref.afterClosed().subscribe(() => {
9585
+ this.isActive.set(false);
9586
+ this.hover.emit(false);
9587
+ });
9588
+ }
9575
9589
  }
9576
9590
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AITableFieldStat, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9577
9591
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: AITableFieldStat, isStandalone: true, selector: "ai-table-field-stat", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { hover: "hover" }, ngImport: i0, template: `
@@ -11973,7 +11987,7 @@ class SelectCellEditorComponent extends AbstractEditCellEditor {
11973
11987
  });
11974
11988
  }
11975
11989
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SelectCellEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
11976
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: SelectCellEditorComponent, isStandalone: true, selector: "select-cell-editor", host: { classAttribute: "d-block h-100 select-cell-editor" }, usesInheritance: true, ngImport: i0, template: "<thy-select\n [(ngModel)]=\"modelValue\"\n [thyAutoExpand]=\"autoFocus()\"\n [thyAllowClear]=\"true\"\n [thyPlaceHolder]=\"''\"\n [thyPreset]=\"preset()\"\n [thyMode]=\"field().settings.is_multiple ? 'multiple' : ''\"\n (ngModelChange)=\"onModelChange($event)\"\n (thyOnExpandStatusChange)=\"onOpenChange($event)\"\n>\n <ng-template #selectedDisplay let-option>\n <select-option [field]=\"field()\" [displayOption]=\"option\"></select-option>\n </ng-template>\n @for (option of selectOptions(); track option._id) {\n <thy-option\n [thyValue]=\"option._id\"\n [hidden]=\"!!option.is_disabled\"\n [thyRawValue]=\"option\"\n [thyShowOptionCustom]=\"true\"\n [thyLabelText]=\"option.text\"\n >\n <select-option [field]=\"field()\" [displayOption]=\"option\"></select-option>\n </thy-option>\n }\n</thy-select>\n", dependencies: [{ kind: "component", type: ThySelect, selector: "thy-select,thy-custom-select", inputs: ["thyDropdownWidthMode", "thyShowSearch", "thyPlaceHolder", "thyServerSearch", "thyLoadState", "thyAutoActiveFirstItem", "thyMode", "thySize", "thyEmptyStateText", "thyEmptySearchMessageText", "thyEnableScrollLoad", "thyAllowClear", "thyDisabled", "thySortComparator", "thyFooterTemplate", "thyPlacement", "thyOrigin", "thyFooterClass", "thyAutoExpand", "thyHasBackdrop", "thyMaxTagCount", "thyBorderless", "thyOptions", "thyPreset"], outputs: ["thyOnSearch", "thyOnScrollToBottom", "thyOnExpandStatusChange"], exportAs: ["thySelect"] }, { kind: "component", type: ThyOption, selector: "thy-option", inputs: ["thyValue", "thyRawValue", "thyLabelText", "thyShowOptionCustom", "thySearchKey", "thyDisabled"], outputs: ["selectionChange", "visibleChange"] }, { kind: "ngmodule", type: ThyTooltipModule }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "ngmodule", type: ThyEmptyModule }, { kind: "ngmodule", type: ThyFormModule }, { 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: "ngmodule", type: ThySelectModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
11990
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: SelectCellEditorComponent, isStandalone: true, selector: "select-cell-editor", host: { classAttribute: "d-block h-100 select-cell-editor" }, usesInheritance: true, ngImport: i0, template: "<thy-select\n [(ngModel)]=\"modelValue\"\n [thyAutoExpand]=\"autoFocus()\"\n [thyAllowClear]=\"true\"\n [thyPlaceHolder]=\"''\"\n [thyPreset]=\"preset()\"\n [thyMode]=\"field().settings.is_multiple ? 'multiple' : ''\"\n (ngModelChange)=\"onModelChange($event)\"\n (thyOnExpandStatusChange)=\"onOpenChange($event)\"\n>\n <ng-template #selectedDisplay let-option>\n <select-option [field]=\"field()\" [displayOption]=\"option\"></select-option>\n </ng-template>\n @for (option of selectOptions(); track option._id) {\n <thy-option\n [thyValue]=\"option._id\"\n [hidden]=\"!!option.is_disabled\"\n [thyRawValue]=\"option\"\n [thyShowOptionCustom]=\"true\"\n [thyLabelText]=\"option.text\"\n >\n <select-option [field]=\"field()\" [displayOption]=\"option\"></select-option>\n </thy-option>\n }\n</thy-select>\n", dependencies: [{ kind: "component", type: ThySelect, selector: "thy-select,thy-custom-select", inputs: ["thyDropdownWidthMode", "thyItemSize", "thyShowSearch", "thyPlaceHolder", "thyServerSearch", "thyLoadState", "thyAutoActiveFirstItem", "thyMode", "thySize", "thyEmptyStateText", "thyEmptySearchMessageText", "thyEnableScrollLoad", "thyAllowClear", "thyDisabled", "thySortComparator", "thyFooterTemplate", "thyPlacement", "thyOrigin", "thyFooterClass", "thyAutoExpand", "thyHasBackdrop", "thyMaxTagCount", "thyBorderless", "thyVirtualScroll", "thyOptions", "thyPreset"], outputs: ["thyOnSearch", "thyOnScrollToBottom", "thyOnExpandStatusChange"], exportAs: ["thySelect"] }, { kind: "component", type: ThyOption, selector: "thy-option", inputs: ["thyValue", "thyRawValue", "thyLabelText", "thyShowOptionCustom", "thySearchKey", "thyDisabled"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: ThyTooltipModule }, { kind: "component", type: SelectOptionComponent, selector: "select-option", inputs: ["field", "displayOption"] }, { kind: "ngmodule", type: ThyEmptyModule }, { kind: "ngmodule", type: ThyFormModule }, { 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: "ngmodule", type: ThySelectModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
11977
11991
  }
11978
11992
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SelectCellEditorComponent, decorators: [{
11979
11993
  type: Component,
@@ -12678,7 +12692,7 @@ class RecordDetailComponent {
12678
12692
  });
12679
12693
  }
12680
12694
  }
12681
- });
12695
+ }) ?? null;
12682
12696
  if (this.fieldMenuPopoverRef) {
12683
12697
  this.fieldMenuPopoverRef.beforeClosed().subscribe(() => {
12684
12698
  if (!isSelfClose) {
@@ -12739,7 +12753,7 @@ class RecordDetailComponent {
12739
12753
  }
12740
12754
  }
12741
12755
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: RecordDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12742
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: RecordDetailComponent, isStandalone: true, selector: "ai-record-detail", inputs: { aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: true, transformFunction: null }, recordId: { classPropertyName: "recordId", publicName: "recordId", isSignal: true, isRequired: true, transformFunction: null }, references: { classPropertyName: "references", publicName: "references", isSignal: true, isRequired: true, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { recordIdChange: "recordIdChange" }, viewQueries: [{ propertyName: "fieldOperationsMenuTemplate", first: true, predicate: ["fieldOperationsMenuTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"d-flex flex-column ai-record-detail\">\n <div class=\"d-flex align-items-center justify-content-between px-5 record-detail-header\">\n <span class=\"record-title\" thyFlexibleText [thyTooltipContent]=\"recordTitle()\">\n {{ recordTitle() }}\n </span>\n\n <div class=\"record-navigation\">\n <button thyButton=\"link-secondary\" thySize=\"md\" [disabled]=\"!recordNavigation()?.hasPrevious\" (click)=\"previousRecord()\">\n <thy-icon thyIconName=\"angle-up\"></thy-icon>\n </button>\n <button thyButton=\"link-secondary\" thySize=\"md\" [disabled]=\"!recordNavigation()?.hasNext\" (click)=\"nextRecord()\">\n <thy-icon thyIconName=\"angle-down\"></thy-icon>\n </button>\n </div>\n <thy-divider [thyVertical]=\"true\"></thy-divider>\n <div class=\"header-operations\">\n <button thyButton=\"link-secondary\" thySize=\"md\" [thyPopover]=\"headerMoreMenu\" thyTrigger=\"click\" thyPlacement=\"bottomRight\">\n <thy-icon thyIconName=\"list\"></thy-icon>\n </button>\n\n <ng-template #headerMoreMenu>\n <div class=\"thy-dropdown-menu\">\n <a thyDropdownMenuItem href=\"javascript:;\" (click)=\"deleteRecord()\">\n <thy-icon thyIconName=\"trash\"></thy-icon>\n <span>{{ i18nTexts().deleteRecord }}</span>\n </a>\n </div>\n </ng-template>\n\n <button thyButton=\"link-secondary\" thySize=\"md\" (click)=\"close()\">\n <thy-icon thyIconName=\"close\"></thy-icon>\n </button>\n </div>\n </div>\n\n <div class=\"record-detail-body\">\n <div class=\"px-8 cell-list-viewport\">\n @for (field of fields(); track field._id) {\n <div class=\"pt-4 cell-item\" [class.active]=\"activeFieldId === field._id\">\n <div #fieldMenuOrigin class=\"d-flex align-items-center justify-content-between mb-2 cell-header\">\n <div class=\"d-flex align-items-center cell-label\">\n <span class=\"d-flex align-items-center mr-2 text-muted font-size-md\">\n @if (fieldIconPath(field)) {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16px\" height=\"16px\" viewBox=\"0 0 16 16\">\n <path [attr.d]=\"fieldIconPath(field)\" fill=\"currentColor\"></path>\n </svg>\n }\n </span>\n <span class=\"d-flex align-items-center font-size-base\">\n {{ field.name }}\n </span>\n </div>\n @if (!readonly()) {\n <a\n class=\"field-action\"\n thyAction\n [thyActionActive]=\"fieldMenuActive()[field._id]\"\n href=\"javascript:;\"\n (click)=\"fieldMenuMoreClick($event, field._id, fieldMenuOrigin)\"\n ><thy-icon thyIconName=\"more-vertical\"></thy-icon\n ></a>\n }\n </div>\n\n <div class=\"dynamic-cell-editor\" (click)=\"cellClick(field._id)\">\n <ai-dynamic-cell-editor\n [aiTable]=\"aiTable()\"\n [fieldId]=\"field._id\"\n [recordId]=\"currentRecordId()\"\n [references]=\"references()\"\n (updateFieldValues)=\"fieldValueChange($event)\"\n >\n </ai-dynamic-cell-editor>\n </div>\n </div>\n }\n </div>\n <div class=\"py-4 px-5\">\n @if (!readonly()) {\n <button class=\"p-0\" thyButton=\"link-secondary\" thySize=\"md\" (click)=\"addNewField($event)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n <span>{{ i18nTexts().addField }}</span>\n </button>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: ThyButton, selector: "thy-button,[thy-button],[thyButton]", inputs: ["thyButton", "thyType", "thyLoading", "thyLoadingText", "thySize", "thyIcon", "thyBlock"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyDivider, selector: "thy-divider", inputs: ["thyVertical", "thyStyle", "thyColor", "thyText", "thyTextDirection", "thyDeeper"] }, { kind: "directive", type: ThyPopoverDirective, selector: "[thyPopover]", inputs: ["thyPopover", "thyTrigger", "thyPlacement", "thyOffset", "thyConfig", "thyShowDelay", "thyHideDelay", "thyAutoAdaptive", "thyDisabled"] }, { kind: "directive", type: ThyDropdownMenuItemDirective, selector: "[thyDropdownMenuItem]", inputs: ["thyType", "thyDisabled"] }, { kind: "component", type: DynamicCellEditorComponent, selector: "ai-dynamic-cell-editor", inputs: ["aiTable", "fieldId", "recordId", "references"], outputs: ["updateFieldValues"] }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
12756
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: RecordDetailComponent, isStandalone: true, selector: "ai-record-detail", inputs: { aiTable: { classPropertyName: "aiTable", publicName: "aiTable", isSignal: true, isRequired: true, transformFunction: null }, recordId: { classPropertyName: "recordId", publicName: "recordId", isSignal: true, isRequired: true, transformFunction: null }, references: { classPropertyName: "references", publicName: "references", isSignal: true, isRequired: true, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { recordIdChange: "recordIdChange" }, viewQueries: [{ propertyName: "fieldOperationsMenuTemplate", first: true, predicate: ["fieldOperationsMenuTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"d-flex flex-column ai-record-detail\">\n <div class=\"d-flex align-items-center justify-content-between pl-8 pr-5 record-detail-header\">\n <span class=\"record-title\" thyFlexibleText [thyTooltipContent]=\"recordTitle()\">\n {{ recordTitle() }}\n </span>\n\n <div class=\"record-navigation\">\n <a thyAction href=\"javascript:;\" [thyDisabled]=\"!recordNavigation()?.hasPrevious\" (click)=\"previousRecord()\"\n ><thy-icon thyIconName=\"angle-up\"></thy-icon\n ></a>\n\n <a thyAction href=\"javascript:;\" [thyDisabled]=\"!recordNavigation()?.hasNext\" (click)=\"nextRecord()\"\n ><thy-icon thyIconName=\"angle-down\"></thy-icon\n ></a>\n </div>\n <thy-divider [thyVertical]=\"true\" thyColor=\"light\"></thy-divider>\n <div class=\"header-operations\">\n <a\n thyAction\n thyActiveClass=\"active\"\n href=\"javascript:;\"\n [thyDropdown]=\"headerMoreMenu\"\n thyTrigger=\"click\"\n thyPlacement=\"bottomRight\"\n ><thy-icon thyIconName=\"list\"></thy-icon\n ></a>\n\n <thy-dropdown-menu #headerMoreMenu>\n <a thyDropdownMenuItem [thyDisabled]=\"readonly()\" href=\"javascript:;\" (click)=\"deleteRecord()\">\n <thy-icon thyIconName=\"trash\"></thy-icon>\n <span>{{ i18nTexts().deleteRecord }}</span>\n </a>\n </thy-dropdown-menu>\n\n <a thyAction href=\"javascript:;\" (click)=\"close()\"><thy-icon thyIconName=\"close\"></thy-icon></a>\n </div>\n </div>\n\n <div class=\"record-detail-body\">\n <div class=\"px-8 cell-list-viewport\">\n @for (field of fields(); track field._id) {\n <div class=\"pt-4 cell-item\" [class.active]=\"activeFieldId === field._id\">\n <div #fieldMenuOrigin class=\"d-flex align-items-center justify-content-between mb-2 cell-header\">\n <div class=\"d-flex align-items-center cell-label\">\n <span class=\"d-flex align-items-center mr-2 text-muted font-size-md\">\n @if (fieldIconPath(field)) {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16px\" height=\"16px\" viewBox=\"0 0 16 16\">\n <path [attr.d]=\"fieldIconPath(field)\" fill=\"currentColor\"></path>\n </svg>\n }\n </span>\n <span class=\"d-flex align-items-center font-size-base\">\n {{ field.name }}\n </span>\n </div>\n @if (!readonly()) {\n <a\n class=\"field-action\"\n thyAction\n [thyActionActive]=\"fieldMenuActive()[field._id]\"\n href=\"javascript:;\"\n (click)=\"fieldMenuMoreClick($event, field._id, fieldMenuOrigin)\"\n ><thy-icon thyIconName=\"more-vertical\"></thy-icon\n ></a>\n }\n </div>\n\n <div class=\"dynamic-cell-editor\" (click)=\"cellClick(field._id)\">\n <ai-dynamic-cell-editor\n [aiTable]=\"aiTable()\"\n [fieldId]=\"field._id\"\n [recordId]=\"currentRecordId()\"\n [references]=\"references()\"\n (updateFieldValues)=\"fieldValueChange($event)\"\n >\n </ai-dynamic-cell-editor>\n </div>\n </div>\n }\n </div>\n <div class=\"py-4 px-5\">\n @if (!readonly()) {\n <button class=\"p-0\" thyButton=\"link-secondary\" thySize=\"md\" (click)=\"addNewField($event)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n <span>{{ i18nTexts().addField }}</span>\n </button>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: ThyButton, selector: "thy-button,[thy-button],[thyButton]", inputs: ["thyButton", "thyType", "thyLoading", "thyLoadingText", "thySize", "thyIcon", "thyBlock"] }, { kind: "component", type: ThyAction, selector: "thy-action, [thyAction]", inputs: ["thyType", "thyIcon", "thyActionIcon", "thyActive", "thyActionActive", "thyTheme", "thyHoverIcon", "thyDisabled"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "component", type: ThyDivider, selector: "thy-divider", inputs: ["thyVertical", "thyStyle", "thyColor", "thyText", "thyTextDirection", "thyDeeper"] }, { kind: "directive", type: 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: "component", type: ThyDropdownMenuComponent, selector: "thy-dropdown-menu", inputs: ["thyWidth", "thyImmediateRender"] }, { kind: "component", type: DynamicCellEditorComponent, selector: "ai-dynamic-cell-editor", inputs: ["aiTable", "fieldId", "recordId", "references"], outputs: ["updateFieldValues"] }, { kind: "component", type: ThyFlexibleText, selector: "thy-flexible-text,[thyFlexibleText]", inputs: ["thyTooltipTrigger", "thyContainerClass", "thyTooltipContent", "thyTooltipPlacement", "thyTooltipOffset"], exportAs: ["thyFlexibleText"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
12743
12757
  }
12744
12758
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: RecordDetailComponent, decorators: [{
12745
12759
  type: Component,
@@ -12748,11 +12762,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
12748
12762
  ThyAction,
12749
12763
  ThyIcon,
12750
12764
  ThyDivider,
12751
- ThyPopoverDirective,
12765
+ ThyDropdownDirective,
12752
12766
  ThyDropdownMenuItemDirective,
12767
+ ThyDropdownMenuComponent,
12753
12768
  DynamicCellEditorComponent,
12754
12769
  ThyFlexibleText
12755
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"d-flex flex-column ai-record-detail\">\n <div class=\"d-flex align-items-center justify-content-between px-5 record-detail-header\">\n <span class=\"record-title\" thyFlexibleText [thyTooltipContent]=\"recordTitle()\">\n {{ recordTitle() }}\n </span>\n\n <div class=\"record-navigation\">\n <button thyButton=\"link-secondary\" thySize=\"md\" [disabled]=\"!recordNavigation()?.hasPrevious\" (click)=\"previousRecord()\">\n <thy-icon thyIconName=\"angle-up\"></thy-icon>\n </button>\n <button thyButton=\"link-secondary\" thySize=\"md\" [disabled]=\"!recordNavigation()?.hasNext\" (click)=\"nextRecord()\">\n <thy-icon thyIconName=\"angle-down\"></thy-icon>\n </button>\n </div>\n <thy-divider [thyVertical]=\"true\"></thy-divider>\n <div class=\"header-operations\">\n <button thyButton=\"link-secondary\" thySize=\"md\" [thyPopover]=\"headerMoreMenu\" thyTrigger=\"click\" thyPlacement=\"bottomRight\">\n <thy-icon thyIconName=\"list\"></thy-icon>\n </button>\n\n <ng-template #headerMoreMenu>\n <div class=\"thy-dropdown-menu\">\n <a thyDropdownMenuItem href=\"javascript:;\" (click)=\"deleteRecord()\">\n <thy-icon thyIconName=\"trash\"></thy-icon>\n <span>{{ i18nTexts().deleteRecord }}</span>\n </a>\n </div>\n </ng-template>\n\n <button thyButton=\"link-secondary\" thySize=\"md\" (click)=\"close()\">\n <thy-icon thyIconName=\"close\"></thy-icon>\n </button>\n </div>\n </div>\n\n <div class=\"record-detail-body\">\n <div class=\"px-8 cell-list-viewport\">\n @for (field of fields(); track field._id) {\n <div class=\"pt-4 cell-item\" [class.active]=\"activeFieldId === field._id\">\n <div #fieldMenuOrigin class=\"d-flex align-items-center justify-content-between mb-2 cell-header\">\n <div class=\"d-flex align-items-center cell-label\">\n <span class=\"d-flex align-items-center mr-2 text-muted font-size-md\">\n @if (fieldIconPath(field)) {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16px\" height=\"16px\" viewBox=\"0 0 16 16\">\n <path [attr.d]=\"fieldIconPath(field)\" fill=\"currentColor\"></path>\n </svg>\n }\n </span>\n <span class=\"d-flex align-items-center font-size-base\">\n {{ field.name }}\n </span>\n </div>\n @if (!readonly()) {\n <a\n class=\"field-action\"\n thyAction\n [thyActionActive]=\"fieldMenuActive()[field._id]\"\n href=\"javascript:;\"\n (click)=\"fieldMenuMoreClick($event, field._id, fieldMenuOrigin)\"\n ><thy-icon thyIconName=\"more-vertical\"></thy-icon\n ></a>\n }\n </div>\n\n <div class=\"dynamic-cell-editor\" (click)=\"cellClick(field._id)\">\n <ai-dynamic-cell-editor\n [aiTable]=\"aiTable()\"\n [fieldId]=\"field._id\"\n [recordId]=\"currentRecordId()\"\n [references]=\"references()\"\n (updateFieldValues)=\"fieldValueChange($event)\"\n >\n </ai-dynamic-cell-editor>\n </div>\n </div>\n }\n </div>\n <div class=\"py-4 px-5\">\n @if (!readonly()) {\n <button class=\"p-0\" thyButton=\"link-secondary\" thySize=\"md\" (click)=\"addNewField($event)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n <span>{{ i18nTexts().addField }}</span>\n </button>\n }\n </div>\n </div>\n</div>\n" }]
12770
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"d-flex flex-column ai-record-detail\">\n <div class=\"d-flex align-items-center justify-content-between pl-8 pr-5 record-detail-header\">\n <span class=\"record-title\" thyFlexibleText [thyTooltipContent]=\"recordTitle()\">\n {{ recordTitle() }}\n </span>\n\n <div class=\"record-navigation\">\n <a thyAction href=\"javascript:;\" [thyDisabled]=\"!recordNavigation()?.hasPrevious\" (click)=\"previousRecord()\"\n ><thy-icon thyIconName=\"angle-up\"></thy-icon\n ></a>\n\n <a thyAction href=\"javascript:;\" [thyDisabled]=\"!recordNavigation()?.hasNext\" (click)=\"nextRecord()\"\n ><thy-icon thyIconName=\"angle-down\"></thy-icon\n ></a>\n </div>\n <thy-divider [thyVertical]=\"true\" thyColor=\"light\"></thy-divider>\n <div class=\"header-operations\">\n <a\n thyAction\n thyActiveClass=\"active\"\n href=\"javascript:;\"\n [thyDropdown]=\"headerMoreMenu\"\n thyTrigger=\"click\"\n thyPlacement=\"bottomRight\"\n ><thy-icon thyIconName=\"list\"></thy-icon\n ></a>\n\n <thy-dropdown-menu #headerMoreMenu>\n <a thyDropdownMenuItem [thyDisabled]=\"readonly()\" href=\"javascript:;\" (click)=\"deleteRecord()\">\n <thy-icon thyIconName=\"trash\"></thy-icon>\n <span>{{ i18nTexts().deleteRecord }}</span>\n </a>\n </thy-dropdown-menu>\n\n <a thyAction href=\"javascript:;\" (click)=\"close()\"><thy-icon thyIconName=\"close\"></thy-icon></a>\n </div>\n </div>\n\n <div class=\"record-detail-body\">\n <div class=\"px-8 cell-list-viewport\">\n @for (field of fields(); track field._id) {\n <div class=\"pt-4 cell-item\" [class.active]=\"activeFieldId === field._id\">\n <div #fieldMenuOrigin class=\"d-flex align-items-center justify-content-between mb-2 cell-header\">\n <div class=\"d-flex align-items-center cell-label\">\n <span class=\"d-flex align-items-center mr-2 text-muted font-size-md\">\n @if (fieldIconPath(field)) {\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16px\" height=\"16px\" viewBox=\"0 0 16 16\">\n <path [attr.d]=\"fieldIconPath(field)\" fill=\"currentColor\"></path>\n </svg>\n }\n </span>\n <span class=\"d-flex align-items-center font-size-base\">\n {{ field.name }}\n </span>\n </div>\n @if (!readonly()) {\n <a\n class=\"field-action\"\n thyAction\n [thyActionActive]=\"fieldMenuActive()[field._id]\"\n href=\"javascript:;\"\n (click)=\"fieldMenuMoreClick($event, field._id, fieldMenuOrigin)\"\n ><thy-icon thyIconName=\"more-vertical\"></thy-icon\n ></a>\n }\n </div>\n\n <div class=\"dynamic-cell-editor\" (click)=\"cellClick(field._id)\">\n <ai-dynamic-cell-editor\n [aiTable]=\"aiTable()\"\n [fieldId]=\"field._id\"\n [recordId]=\"currentRecordId()\"\n [references]=\"references()\"\n (updateFieldValues)=\"fieldValueChange($event)\"\n >\n </ai-dynamic-cell-editor>\n </div>\n </div>\n }\n </div>\n <div class=\"py-4 px-5\">\n @if (!readonly()) {\n <button class=\"p-0\" thyButton=\"link-secondary\" thySize=\"md\" (click)=\"addNewField($event)\">\n <thy-icon thyIconName=\"plus\"></thy-icon>\n <span>{{ i18nTexts().addField }}</span>\n </button>\n }\n </div>\n </div>\n</div>\n" }]
12756
12771
  }], ctorParameters: () => [], propDecorators: { aiTable: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiTable", required: true }] }], recordId: [{ type: i0.Input, args: [{ isSignal: true, alias: "recordId", required: true }] }], references: [{ type: i0.Input, args: [{ isSignal: true, alias: "references", required: true }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], recordIdChange: [{ type: i0.Output, args: ["recordIdChange"] }], fieldOperationsMenuTemplate: [{ type: i0.ViewChild, args: ['fieldOperationsMenuTemplate', { isSignal: true }] }] } });
12757
12772
 
12758
12773
  class AITableGridEventService {
@@ -12914,7 +12929,7 @@ class AITableGridEventService {
12914
12929
  manualClosure: true,
12915
12930
  animationDisabled: true,
12916
12931
  autoAdaptive: true
12917
- });
12932
+ }) ?? null;
12918
12933
  if (this.cellEditorPopoverRef) {
12919
12934
  const wheelEvent = fromEvent(this.cellEditorPopoverRef.componentInstance.elementRef.nativeElement, 'wheel').subscribe((event) => {
12920
12935
  const field = aiTable.fieldsMap()[fieldId];
@@ -13452,8 +13467,8 @@ class RecordDetailService {
13452
13467
  this.config = null;
13453
13468
  }
13454
13469
  open(config) {
13455
- if (this.isOpen()) {
13456
- this.currentSlideRef?.componentInstance.setSelection(config.recordId);
13470
+ if (this.isOpen() && this.currentSlideRef) {
13471
+ this.currentSlideRef.componentInstance.setSelection(config.recordId);
13457
13472
  return this.currentSlideRef;
13458
13473
  }
13459
13474
  this.config = config;
@@ -13470,7 +13485,7 @@ class RecordDetailService {
13470
13485
  actions: config.actions
13471
13486
  },
13472
13487
  ...config.slideConfig
13473
- });
13488
+ }) ?? null;
13474
13489
  if (this.currentSlideRef) {
13475
13490
  this.currentSlideRef.afterOpened().subscribe(() => {
13476
13491
  this.setupDocumentClickListener(config);
@@ -13479,6 +13494,9 @@ class RecordDetailService {
13479
13494
  this.close();
13480
13495
  });
13481
13496
  }
13497
+ if (!this.currentSlideRef) {
13498
+ throw new Error('Failed to open slide');
13499
+ }
13482
13500
  return this.currentSlideRef;
13483
13501
  }
13484
13502
  close() {