@ai-table/grid 0.4.7 → 0.4.9

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.
@@ -48,17 +48,21 @@
48
48
  }
49
49
 
50
50
  .cell-item {
51
+ .field-action {
52
+ margin-right: -15px;
53
+ display: none;
54
+ &.active {
55
+ display: block;
56
+ }
57
+ }
58
+ &:hover {
59
+ .field-action {
60
+ display: block;
61
+ }
62
+ }
63
+
51
64
  .cell-header {
52
65
  height: 22px;
53
-
54
- .cell-operations {
55
- opacity: 0;
56
- transition: opacity 0.2s;
57
-
58
- &.visible {
59
- opacity: 1;
60
- }
61
- }
62
66
  }
63
67
 
64
68
  .dynamic-cell-editor {
@@ -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() {
@@ -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" }] : []));
@@ -9310,8 +9322,7 @@ class AITableFieldStat {
9310
9322
  aiTable,
9311
9323
  getFieldValue: (record, options) => {
9312
9324
  const { aiTable, field } = options;
9313
- const cellValue = AITableQueries.getFieldValue(aiTable, [record._id, field._id]);
9314
- return transformToCellText(cellValue, options);
9325
+ return AITableQueries.getFieldValue(aiTable, [record._id, field._id]);
9315
9326
  }
9316
9327
  };
9317
9328
  }, ...(ngDevMode ? [{ debugName: "options" }] : []));
@@ -12508,9 +12519,7 @@ class DynamicCellEditorComponent {
12508
12519
  }
12509
12520
  catch (error) { }
12510
12521
  const fieldRenderers = this.aiTable().context?.aiFieldConfig()?.fieldRenderers;
12511
- this.editorComponentRef = editorHost?.createComponent(editorComponent, {
12512
- injector: fieldRenderers?.[field.type]?.recordCellEditorInjector
12513
- });
12522
+ this.editorComponentRef = editorHost?.createComponent(editorComponent, {});
12514
12523
  const instance = this.editorComponentRef.instance;
12515
12524
  if (instance instanceof AbstractEditCellEditor) {
12516
12525
  this.editorComponentRef.setInput('aiTable', this.aiTable());
@@ -12621,7 +12630,6 @@ class RecordDetailComponent {
12621
12630
  return [];
12622
12631
  }, ...(ngDevMode ? [{ debugName: "fieldMenus" }] : []));
12623
12632
  this.activeFieldId = null;
12624
- this.fieldMenuVisible = signal({}, ...(ngDevMode ? [{ debugName: "fieldMenuVisible" }] : []));
12625
12633
  this.fieldMenuActive = signal({}, ...(ngDevMode ? [{ debugName: "fieldMenuActive" }] : []));
12626
12634
  this.fieldMenuPopoverRef = null;
12627
12635
  this.slideRef = inject(ThySlideRef);
@@ -12661,35 +12669,23 @@ class RecordDetailComponent {
12661
12669
  cellClick(fieldId) {
12662
12670
  this.activateCell(fieldId);
12663
12671
  }
12664
- showFieldMenu(fieldId) {
12665
- this.fieldMenuVisible.set({ [fieldId]: true });
12666
- }
12667
- hideFieldMenu(fieldId) {
12668
- if (!this.fieldMenuPopoverRef) {
12669
- this.fieldMenuVisible.set({ [fieldId]: false });
12670
- }
12671
- }
12672
- fieldMenuMoreClick(e, fieldId) {
12673
- const origin = e.target;
12674
- const position = origin.getBoundingClientRect();
12675
- this.fieldMenuVisible.set({ [fieldId]: true });
12672
+ fieldMenuMoreClick(e, fieldId, fieldMenuOrigin) {
12673
+ const origin = e.currentTarget;
12674
+ const position = fieldMenuOrigin.getBoundingClientRect();
12676
12675
  this.fieldMenuActive.set({ [fieldId]: true });
12677
12676
  let isSelfClose = false;
12678
12677
  this.fieldMenuPopoverRef = this.thyPopover.open(AITableFieldMenu, {
12679
12678
  origin,
12680
12679
  placement: 'bottomRight',
12681
- manualClosure: true,
12682
12680
  initialState: {
12683
12681
  aiTable: this.aiTable(),
12684
12682
  fieldId,
12685
12683
  fieldMenus: this.fieldMenus(),
12686
- origin,
12684
+ origin: fieldMenuOrigin,
12687
12685
  position,
12688
12686
  execMenuCallback: (data) => {
12689
12687
  isSelfClose = true;
12690
- this.thyPopover.close();
12691
12688
  data.popoverRef?.beforeClosed().subscribe(() => {
12692
- this.fieldMenuVisible.set({ [fieldId]: false });
12693
12689
  this.fieldMenuActive.set({ [fieldId]: false });
12694
12690
  });
12695
12691
  }
@@ -12698,7 +12694,6 @@ class RecordDetailComponent {
12698
12694
  if (this.fieldMenuPopoverRef) {
12699
12695
  this.fieldMenuPopoverRef.beforeClosed().subscribe(() => {
12700
12696
  if (!isSelfClose) {
12701
- this.fieldMenuVisible.set({ [fieldId]: false });
12702
12697
  this.fieldMenuActive.set({ [fieldId]: false });
12703
12698
  }
12704
12699
  this.fieldMenuPopoverRef = null;
@@ -12756,7 +12751,7 @@ class RecordDetailComponent {
12756
12751
  }
12757
12752
  }
12758
12753
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: RecordDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12759
- 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\n class=\"pt-4 cell-item\"\n [class.active]=\"activeFieldId === field._id\"\n (mouseenter)=\"showFieldMenu(field._id)\"\n (mouseleave)=\"hideFieldMenu(field._id)\"\n >\n <div 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 <div class=\"cell-operations\" [class.visible]=\"fieldMenuVisible()[field._id]\">\n <a\n thyAction\n [thyActionActive]=\"fieldMenuActive()[field._id]\"\n href=\"javascript:;\"\n (click)=\"fieldMenuMoreClick($event, field._id)\"\n ><thy-icon thyIconName=\"more-vertical\"></thy-icon\n ></a>\n </div>\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 }); }
12754
+ 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 }); }
12760
12755
  }
12761
12756
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: RecordDetailComponent, decorators: [{
12762
12757
  type: Component,
@@ -12765,11 +12760,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
12765
12760
  ThyAction,
12766
12761
  ThyIcon,
12767
12762
  ThyDivider,
12768
- ThyPopoverDirective,
12763
+ ThyDropdownDirective,
12769
12764
  ThyDropdownMenuItemDirective,
12765
+ ThyDropdownMenuComponent,
12770
12766
  DynamicCellEditorComponent,
12771
12767
  ThyFlexibleText
12772
- ], 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\n class=\"pt-4 cell-item\"\n [class.active]=\"activeFieldId === field._id\"\n (mouseenter)=\"showFieldMenu(field._id)\"\n (mouseleave)=\"hideFieldMenu(field._id)\"\n >\n <div 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 <div class=\"cell-operations\" [class.visible]=\"fieldMenuVisible()[field._id]\">\n <a\n thyAction\n [thyActionActive]=\"fieldMenuActive()[field._id]\"\n href=\"javascript:;\"\n (click)=\"fieldMenuMoreClick($event, field._id)\"\n ><thy-icon thyIconName=\"more-vertical\"></thy-icon\n ></a>\n </div>\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" }]
12768
+ ], 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" }]
12773
12769
  }], 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 }] }] } });
12774
12770
 
12775
12771
  class AITableGridEventService {
@@ -13478,6 +13474,7 @@ class RecordDetailService {
13478
13474
  from: 'right',
13479
13475
  width: '480px',
13480
13476
  hasBackdrop: false,
13477
+ viewContainerRef: config.viewContainerRef,
13481
13478
  panelClass: 'ai-expand-record-slide',
13482
13479
  initialState: {
13483
13480
  aiTable: config.aiTable,