@ai-table/grid 0.5.1 → 0.5.3

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.
@@ -76,3 +76,12 @@
76
76
  }
77
77
  }
78
78
  }
79
+
80
+ .ai-table-record-detail-remove {
81
+ &:hover {
82
+ .thy-icon {
83
+ color: variables.$danger !important;
84
+ }
85
+ color: variables.$danger !important;
86
+ }
87
+ }
@@ -6958,7 +6958,7 @@ class GroupLayout extends Layout {
6958
6958
  return;
6959
6959
  const { row, indexStyle } = config;
6960
6960
  const { _id: groupValue, fieldId } = row;
6961
- const { field, style, aiTable } = render;
6961
+ const { field, style, aiTable, cellValue } = render;
6962
6962
  const y = this.y;
6963
6963
  const rowHeight = this.rowHeight;
6964
6964
  const { fill: indexFill } = indexStyle || { fill: this.colors.white };
@@ -6986,7 +6986,7 @@ class GroupLayout extends Layout {
6986
6986
  });
6987
6987
  }
6988
6988
  const iconContainerWidth = AI_TABLE_ICON_COMMON_SIZE + AI_TABLE_FIELD_HEAD_ICON_GAP_SIZE;
6989
- if (!isEmpty(groupValue) || [AITableFieldType.checkbox, AITableFieldType.progress].includes(field.type)) {
6989
+ if (!isEmpty(cellValue) || [AITableFieldType.checkbox, AITableFieldType.progress].includes(field.type)) {
6990
6990
  cellDrawer.initStyle(field, style);
6991
6991
  const statContainerWidth = aiTable.context?.groupStatContainerWidthMap()?.get(`${config.row.groupId}:${fieldId}`);
6992
6992
  const widthOffset = statContainerWidth ? statContainerWidth - AI_TABLE_CELL_PADDING : 0;
@@ -11830,11 +11830,10 @@ function toggleSelectAllRecords(aiTable, checked) {
11830
11830
  }
11831
11831
  function getNextRecordByActiveCell(aiTable) {
11832
11832
  const records = aiTable.gridData().records;
11833
- const visibleRowsIndexMap = aiTable.context.visibleRowsIndexMap();
11834
11833
  const currentId = aiTable.selection().activeCell?.[0];
11835
11834
  if (!currentId)
11836
11835
  return null;
11837
- const currentIndex = visibleRowsIndexMap.get(currentId) || 0;
11836
+ const currentIndex = records.findIndex((item) => item._id === currentId);
11838
11837
  if (currentIndex === -1 || currentIndex === records.length - 1) {
11839
11838
  return null;
11840
11839
  }
@@ -11843,11 +11842,10 @@ function getNextRecordByActiveCell(aiTable) {
11843
11842
  }
11844
11843
  function getPreviousRecordByActiveCell(aiTable) {
11845
11844
  const records = aiTable.gridData().records;
11846
- const visibleRowsIndexMap = aiTable.context.visibleRowsIndexMap();
11847
11845
  const currentId = aiTable.selection().activeCell?.[0];
11848
11846
  if (!currentId)
11849
11847
  return null;
11850
- const currentIndex = visibleRowsIndexMap.get(currentId) || 0;
11848
+ const currentIndex = records.findIndex((item) => item._id === currentId);
11851
11849
  if (currentIndex <= 0) {
11852
11850
  return null;
11853
11851
  }
@@ -11856,8 +11854,7 @@ function getPreviousRecordByActiveCell(aiTable) {
11856
11854
  }
11857
11855
  function getRecordNavigationInfo(aiTable, recordId) {
11858
11856
  const records = aiTable.gridData().records;
11859
- const visibleRowsIndexMap = aiTable.context.visibleRowsIndexMap();
11860
- const index = visibleRowsIndexMap.get(recordId) || 0;
11857
+ const index = records.findIndex((item) => item._id === recordId);
11861
11858
  if (index === -1)
11862
11859
  return null;
11863
11860
  return {
@@ -12592,13 +12589,13 @@ class RecordDetailComponent {
12592
12589
  }
12593
12590
  constructor() {
12594
12591
  this.aiTable = input.required(...(ngDevMode ? [{ debugName: "aiTable" }] : []));
12595
- this.recordId = input.required(...(ngDevMode ? [{ debugName: "recordId" }] : []));
12592
+ this.recordId = model.required(...(ngDevMode ? [{ debugName: "recordId" }] : []));
12596
12593
  this.references = input.required(...(ngDevMode ? [{ debugName: "references" }] : []));
12597
12594
  this.actions = input(...(ngDevMode ? [undefined, { debugName: "actions" }] : []));
12598
12595
  this.recordIdChange = output();
12599
12596
  this.internalRecordId = signal('', ...(ngDevMode ? [{ debugName: "internalRecordId" }] : []));
12600
12597
  this.readonly = computed(() => {
12601
- return this.aiTable().context?.readonly?.();
12598
+ return this.aiTable()?.context?.readonly?.();
12602
12599
  }, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
12603
12600
  this.currentRecordId = computed(() => {
12604
12601
  const inputId = this.recordId();
@@ -12655,6 +12652,13 @@ class RecordDetailComponent {
12655
12652
  this.fieldMenuPopoverRef = null;
12656
12653
  this.slideRef = inject(ThySlideRef);
12657
12654
  this.thyPopover = inject(ThyPopover);
12655
+ effect(() => {
12656
+ const recordId = this.recordId();
12657
+ untracked(() => {
12658
+ this.setSelection(recordId);
12659
+ this.internalRecordId.set(recordId);
12660
+ });
12661
+ });
12658
12662
  effect(() => {
12659
12663
  const activeCell = this.aiTable().selection().activeCell;
12660
12664
  if (activeCell) {
@@ -12662,9 +12666,8 @@ class RecordDetailComponent {
12662
12666
  }
12663
12667
  });
12664
12668
  }
12665
- ngOnInit() {
12666
- this.setSelection(this.recordId());
12667
- this.internalRecordId.set(this.recordId());
12669
+ updateRecordId(recordId) {
12670
+ this.recordId.set(recordId);
12668
12671
  }
12669
12672
  close() {
12670
12673
  this.slideRef?.close();
@@ -12672,15 +12675,13 @@ class RecordDetailComponent {
12672
12675
  previousRecord() {
12673
12676
  const prevId = getPreviousRecordByActiveCell(this.aiTable());
12674
12677
  if (prevId) {
12675
- this.internalRecordId.set(prevId);
12676
- this.setSelection(prevId);
12678
+ this.updateRecordId(prevId);
12677
12679
  }
12678
12680
  }
12679
12681
  nextRecord() {
12680
12682
  const nextId = getNextRecordByActiveCell(this.aiTable());
12681
12683
  if (nextId) {
12682
- this.internalRecordId.set(nextId);
12683
- this.setSelection(nextId);
12684
+ this.updateRecordId(nextId);
12684
12685
  }
12685
12686
  }
12686
12687
  deleteRecord() {
@@ -12695,23 +12696,24 @@ class RecordDetailComponent {
12695
12696
  const position = fieldMenuOrigin.getBoundingClientRect();
12696
12697
  this.fieldMenuActive.set({ [fieldId]: true });
12697
12698
  let isSelfClose = false;
12698
- this.fieldMenuPopoverRef = this.thyPopover.open(AITableFieldMenu, {
12699
- origin,
12700
- placement: 'bottomRight',
12701
- initialState: {
12702
- aiTable: this.aiTable(),
12703
- fieldId,
12704
- fieldMenus: this.fieldMenus(),
12705
- origin: fieldMenuOrigin,
12706
- position,
12707
- execMenuCallback: (data) => {
12708
- isSelfClose = true;
12709
- data.popoverRef?.beforeClosed().subscribe(() => {
12710
- this.fieldMenuActive.set({ [fieldId]: false });
12711
- });
12699
+ this.fieldMenuPopoverRef =
12700
+ this.thyPopover.open(AITableFieldMenu, {
12701
+ origin,
12702
+ placement: 'bottomRight',
12703
+ initialState: {
12704
+ aiTable: this.aiTable(),
12705
+ fieldId,
12706
+ fieldMenus: this.fieldMenus(),
12707
+ origin: fieldMenuOrigin,
12708
+ position,
12709
+ execMenuCallback: (data) => {
12710
+ isSelfClose = true;
12711
+ data.popoverRef?.beforeClosed().subscribe(() => {
12712
+ this.fieldMenuActive.set({ [fieldId]: false });
12713
+ });
12714
+ }
12712
12715
  }
12713
- }
12714
- }) ?? null;
12716
+ }) ?? null;
12715
12717
  if (this.fieldMenuPopoverRef) {
12716
12718
  this.fieldMenuPopoverRef.beforeClosed().subscribe(() => {
12717
12719
  if (!isSelfClose) {
@@ -12772,7 +12774,7 @@ class RecordDetailComponent {
12772
12774
  }
12773
12775
  }
12774
12776
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: RecordDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
12775
- 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 }); }
12777
+ 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: { recordId: "recordIdChange", 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\n class=\"ai-table-record-detail-remove\"\n thyDropdownMenuItem\n [thyDisabled]=\"readonly()\"\n href=\"javascript:;\"\n (click)=\"deleteRecord()\"\n >\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 }); }
12776
12778
  }
12777
12779
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: RecordDetailComponent, decorators: [{
12778
12780
  type: Component,
@@ -12786,8 +12788,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
12786
12788
  ThyDropdownMenuComponent,
12787
12789
  DynamicCellEditorComponent,
12788
12790
  ThyFlexibleText
12789
- ], 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" }]
12790
- }], 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 }] }] } });
12791
+ ], 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\n class=\"ai-table-record-detail-remove\"\n thyDropdownMenuItem\n [thyDisabled]=\"readonly()\"\n href=\"javascript:;\"\n (click)=\"deleteRecord()\"\n >\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" }]
12792
+ }], ctorParameters: () => [], propDecorators: { aiTable: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiTable", required: true }] }], recordId: [{ type: i0.Input, args: [{ isSignal: true, alias: "recordId", required: true }] }, { type: i0.Output, args: ["recordIdChange"] }], 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 }] }] } });
12791
12793
 
12792
12794
  class AITableGridEventService {
12793
12795
  constructor() {
@@ -13487,24 +13489,28 @@ class RecordDetailService {
13487
13489
  }
13488
13490
  open(config) {
13489
13491
  if (this.isOpen() && this.currentSlideRef) {
13490
- this.currentSlideRef.componentInstance.setSelection(config.recordId);
13492
+ const componentInstance = this.currentSlideRef.componentInstance;
13493
+ if (componentInstance && componentInstance.recordId() !== config.recordId) {
13494
+ componentInstance.updateRecordId(config.recordId);
13495
+ }
13491
13496
  return this.currentSlideRef;
13492
13497
  }
13493
13498
  this.config = config;
13494
- this.currentSlideRef = this.thySlide.open(RecordDetailComponent, {
13495
- from: 'right',
13496
- width: '480px',
13497
- hasBackdrop: false,
13498
- viewContainerRef: config.viewContainerRef,
13499
- panelClass: 'ai-expand-record-slide',
13500
- initialState: {
13501
- aiTable: config.aiTable,
13502
- recordId: config.recordId,
13503
- references: config.references,
13504
- actions: config.actions
13505
- },
13506
- ...config.slideConfig
13507
- }) ?? null;
13499
+ this.currentSlideRef =
13500
+ this.thySlide.open(RecordDetailComponent, {
13501
+ from: 'right',
13502
+ width: '480px',
13503
+ hasBackdrop: false,
13504
+ viewContainerRef: config.viewContainerRef,
13505
+ panelClass: 'ai-expand-record-slide',
13506
+ initialState: {
13507
+ aiTable: config.aiTable,
13508
+ recordId: config.recordId,
13509
+ references: config.references,
13510
+ actions: config.actions
13511
+ },
13512
+ ...config.slideConfig
13513
+ }) ?? null;
13508
13514
  if (this.currentSlideRef) {
13509
13515
  this.currentSlideRef.afterOpened().subscribe(() => {
13510
13516
  this.setupDocumentClickListener(config);
@@ -14781,7 +14787,7 @@ class AITableGrid extends AITableGridBase {
14781
14787
  if (!focused) {
14782
14788
  return true;
14783
14789
  }
14784
- const hasAITableGrid = focused.querySelector('ai-table-grid') !== null;
14790
+ const hasAITableGrid = focused.closest('ai-table-grid') !== null || focused.closest('.ai-table-prevent-clear-selection') !== null;
14785
14791
  if (!hasAITableGrid) {
14786
14792
  return true;
14787
14793
  }