Skip to content

Commit f6db67d

Browse files
authored
Merge branch 'master' into dependabot/npm_and_yarn/npm_and_yarn-6f7de852b0
2 parents 06b500a + d36c05b commit f6db67d

11 files changed

Lines changed: 189 additions & 27 deletions

File tree

.github/workflows/npm-publish.yml

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
- uses: actions/checkout@v4
1515
- uses: actions/setup-node@v4
1616
with:
17-
node-version: 22
17+
node-version: '22.22.1' # Specifically avoid 22.22.2 due to a regression with npm latest
1818
cache: 'npm'
1919
registry-url: 'https://registry.npmjs.org'
2020

@@ -87,3 +87,25 @@ jobs:
8787
- name: Publish igniteui-angular-extras
8888
run: npm publish --tag ${NPM_TAG}
8989
working-directory: dist/igniteui-angular-extras
90+
91+
dispatch-api-update:
92+
needs: build
93+
runs-on: ubuntu-latest
94+
steps:
95+
- name: Get app token
96+
id: app-token
97+
uses: actions/create-github-app-token@v2
98+
with:
99+
app-id: ${{ secrets.IGNITEUI_GITHUB_APP_ID }}
100+
private-key: ${{ secrets.IGNITEUI_GITHUB_APP_PRIVATE_KEY }}
101+
owner: IgniteUI
102+
- name: Trigger API update workflow
103+
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697
104+
with:
105+
token: ${{ steps.app-token.outputs.token }}
106+
repository: IgniteUI/igniteui-angular-api-i18n
107+
event-type: api-update
108+
client-payload: |
109+
{
110+
"release_tag": "${{ github.event.release.tag_name }}"
111+
}

projects/igniteui-angular/core/src/data-operations/merge-strategy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export class DefaultMergeStrategy implements IGridMergeStrategy {
7474
index++;
7575
continue;
7676
}
77-
const recToUpdateData = recData ?? { recordRef: grid.isGhostRecord(rec) ? rec.recordRef : rec, cellMergeMeta: new Map<string, IMergeByResult>(), ghostRecord: rec.ghostRecord };
77+
const recToUpdateData = recData ?? { recordRef: grid.isGhostRecord(rec) ? rec.recordRef : rec, cellMergeMeta: new Map<string, IMergeByResult>(), ghostRecord: rec.ghostRecord, index: index };
7878
recToUpdateData.cellMergeMeta.set(field, { rowSpan: 1, childRecords: [] });
7979
if (prev && comparer.call(this, prev.recordRef, recToUpdateData.recordRef, field, isDate, isTime) && prev.ghostRecord === recToUpdateData.ghostRecord) {
8080
const root = prev.cellMergeMeta.get(field)?.root ?? prev;

projects/igniteui-angular/core/src/grid-column-actions/token.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export abstract class IgxActionStripToken {
77
public abstract cdr: ChangeDetectorRef
88
public abstract context: any;
99
public abstract menuOverlaySettings: OverlaySettings;
10+
public abstract actionButtons: QueryList<IgxActionStripActionsToken>;
1011
public abstract get hideOnRowLeave(): boolean;
1112

1213
public abstract show(context?: any): void;

projects/igniteui-angular/directives/src/directives/for-of/for_of.directive.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,11 @@ export class IgxForOfDirective<T, U extends T[] = T[]> extends IgxForOfToken<T,U
275275
protected _differ: IterableDiffer<T> | null = null;
276276
protected _trackByFn: TrackByFunction<T>;
277277
protected individualSizeCache: number[] = [];
278+
/**
279+
* @hidden
280+
*/
278281
/** Internal track for scroll top that is being virtualized */
279-
protected _virtScrollPosition = 0;
282+
public _virtScrollPosition = 0;
280283
/** If the next onScroll event is triggered due to internal setting of scrollTop */
281284
protected _bScrollInternal = false;
282285
// End properties related to virtual height handling
@@ -901,7 +904,7 @@ export class IgxForOfDirective<T, U extends T[] = T[]> extends IgxForOfToken<T,U
901904
const maxVirtScrollTop = this._virtSize - containerSize;
902905
this._bScrollInternal = true;
903906
this._virtScrollPosition = maxVirtScrollTop;
904-
this.scrollPosition = maxVirtScrollTop;
907+
this.scrollPosition = maxVirtScrollTop / this._virtRatio;
905908
return;
906909
}
907910
if (this._adjustToIndex) {
@@ -1529,11 +1532,12 @@ export class IgxForOfDirective<T, U extends T[] = T[]> extends IgxForOfToken<T,U
15291532
let currentScroll = this.scrollPosition;
15301533
if (this._virtRatio !== 1) {
15311534
this._calcVirtualScrollPosition(this.scrollPosition);
1532-
currentScroll = this._virtScrollPosition;
1535+
scrollOffset = this.fixedUpdateAllElements(this._virtScrollPosition);
1536+
} else {
1537+
const scroll = this.scrollComponent.nativeElement;
1538+
scrollOffset = scroll && this.scrollComponent.size ?
1539+
currentScroll - this.sizesCache[this.state.startIndex] : 0;
15331540
}
1534-
const scroll = this.scrollComponent.nativeElement;
1535-
scrollOffset = scroll && this.scrollComponent.size ?
1536-
currentScroll - this.sizesCache[this.state.startIndex] : 0;
15371541
const dir = this.igxForScrollOrientation === 'horizontal' ? 'left' : 'transform';
15381542
this.dc.instance._viewContainer.element.nativeElement.style[dir] = this.igxForScrollOrientation === 'horizontal' ?
15391543
-(scrollOffset) + 'px' :

projects/igniteui-angular/grids/core/src/grid-actions/grid-pinning-actions.component.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,26 @@ describe('igxGridPinningActions #grid ', () => {
7171
const secondToLastVisible = grid.rowList.toArray()[grid.rowList.length - 2];
7272
expect(secondToLastVisible.key).toEqual('FAMIA');
7373
});
74+
75+
it('should not hide action strip in base mode when scrollToRow is invoked', () => {
76+
grid.pinRow('FAMIA');
77+
fixture.detectChanges();
78+
79+
const pinnedRow = grid.pinnedRows[0];
80+
actionStrip.show(pinnedRow);
81+
fixture.detectChanges();
82+
83+
const pinningActions = fixture.debugElement.query(By.directive(IgxGridPinningActionsComponent))
84+
.componentInstance as IgxGridPinningActionsComponent;
85+
spyOn<any>(grid, 'scrollTo');
86+
87+
pinningActions.scrollToRow(null);
88+
fixture.detectChanges();
89+
90+
expect((grid as any).scrollTo).toHaveBeenCalledWith(pinnedRow.data, 0);
91+
expect(actionStrip.hidden).toBeFalse();
92+
expect(actionStrip.context).toBe(pinnedRow);
93+
});
7494
});
7595

7696
describe('Menu ', () => {

projects/igniteui-angular/grids/core/src/grid-actions/grid-pinning-actions.component.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ export class IgxGridPinningActionsComponent extends IgxGridActionsBaseDirective
126126
const context = this.strip.context;
127127
const grid = context.grid;
128128
grid.scrollTo(context.data, 0);
129-
this.strip.hide();
129+
130+
if (this.asMenuItems) {
131+
this.strip.hide();
132+
}
130133
}
131134

132135
private registerSVGIcons(): void {

projects/igniteui-angular/grids/grid/src/grid-add-row.spec.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { TestBed, fakeAsync, tick, waitForAsync } from '@angular/core/testing';
44
import { DebugElement } from '@angular/core';
55
import { GridFunctions, GridSummaryFunctions } from '../../../test-utils/grid-functions.spec';
66
import {
7-
IgxAddRowComponent, IgxGridRowEditingDefinedColumnsComponent, IgxGridRowEditingTransactionComponent
7+
IgxAddRowComponent, IgxGridRowEditingDefinedColumnsComponent, IgxGridRowEditingTransactionComponent,
8+
GridDynamicActionStripComponent
89
} from '../../../test-utils/grid-samples.spec';
910

1011
import { By } from '@angular/platform-browser';
@@ -45,7 +46,8 @@ describe('IgxGrid - Row Adding #grid', () => {
4546
IgxGridRowEditingTransactionComponent,
4647
IgxGridRowEditingDefinedColumnsComponent,
4748
ColumnLayoutTestComponent,
48-
DefaultGridMasterDetailComponent
49+
DefaultGridMasterDetailComponent,
50+
GridDynamicActionStripComponent
4951
],
5052
providers: [
5153
IgxGridMRLNavigationService
@@ -1121,4 +1123,32 @@ describe('IgxGrid - Row Adding #grid', () => {
11211123
expect(grid.rowChangesCount).toEqual(3);
11221124
});
11231125
});
1126+
1127+
describe('ActionStrip - Dynamic Addition', () => {
1128+
beforeEach(() => {
1129+
fixture = TestBed.createComponent(GridDynamicActionStripComponent);
1130+
fixture.detectChanges();
1131+
grid = fixture.componentInstance.grid;
1132+
});
1133+
1134+
it('Should set outlet for actionstrip menu when added post-init', async () => {
1135+
// Verify no actionstrip initially
1136+
expect(fixture.componentInstance.actionStrip).toBeUndefined();
1137+
expect(grid.actionStrip).toBeUndefined();
1138+
1139+
// Add the actionstrip dynamically
1140+
fixture.componentInstance.showActionStrip = true;
1141+
fixture.detectChanges();
1142+
await wait(16);
1143+
1144+
// Get reference to the actionstrip
1145+
actionStrip = fixture.componentInstance.actionStrip;
1146+
expect(actionStrip).toBeDefined();
1147+
expect(grid.actionStrip).toBeDefined();
1148+
1149+
// Verify that the outlet is properly set
1150+
expect(actionStrip.menuOverlaySettings.outlet).toBeDefined();
1151+
expect(actionStrip.menuOverlaySettings.outlet).toBe(grid.outlet);
1152+
});
1153+
});
11241154
});

projects/igniteui-angular/grids/grid/src/grid-base.directive.ts

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ import { IgxGridRowComponent } from './grid-row.component';
108108
import { IgxGridGroupByAreaComponent } from './grouping/grid-group-by-area.component';
109109
import { IgxPaginatorToken, type IgxPaginatorComponent } from 'igniteui-angular/paginator';
110110
import { IgxSnackbarComponent } from 'igniteui-angular/snackbar';
111-
import { CharSeparatedValueData, DropPosition, FilterMode, getUUID, GridCellMergeMode, GridKeydownTargetType, GridPagingMode, GridSelectionMode, GridSelectionRange, GridServiceType, GridSummaryPosition, GridType, GridValidationTrigger, IActiveNode, IActiveNodeChangeEventArgs, ICellPosition, IClipboardOptions, IColumnMovingEndEventArgs, IColumnMovingEventArgs, IColumnMovingStartEventArgs, IColumnResizeEventArgs, IColumnsAutoGeneratedEventArgs, IColumnSelectionEventArgs, IColumnVisibilityChangedEventArgs, IColumnVisibilityChangingEventArgs, IFilteringEventArgs, IGridCellEventArgs, IGridClipboardEvent, IGridContextMenuEventArgs, IGridEditDoneEventArgs, IGridEditEventArgs, IGridFormGroupCreatedEventArgs, IGridKeydownEventArgs, IGridRowEventArgs, IGridScrollEventArgs, IGridToolbarExportEventArgs, IGridValidationStatusEventArgs, IGX_GRID_SERVICE_BASE, IgxAdvancedFilteringDialogComponent, IgxCell, IgxColumnComponent, IgxColumnGroupComponent, IgxColumnResizingService, IgxDragIndicatorIconDirective, IgxEditRow, IgxExcelStyleHeaderIconDirective, IgxExcelStyleLoadingValuesTemplateDirective, IgxFilteringService, IgxGridBodyDirective, IgxGridCellComponent, IgxGridColumnResizerComponent, IgxGridEmptyTemplateContext, IgxGridEmptyTemplateDirective, IgxGridExcelStyleFilteringComponent, IgxGridFilteringCellComponent, IgxGridFilteringRowComponent, IgxGridHeaderComponent, IgxGridHeaderGroupComponent, IgxGridHeaderRowComponent, IgxGridHeaderTemplateContext, IgxGridLoadingTemplateDirective, IgxGridNavigationService, IgxGridRowDragGhostContext, IgxGridRowEditActionsTemplateContext, IgxGridRowEditTemplateContext, IgxGridRowEditTextTemplateContext, IgxGridRowTemplateContext, IgxGridSelectionService, IgxGridSummaryService, IgxGridTemplateContext, IgxGridToolbarComponent, IgxGridTransaction, IgxGridValidationService, IgxHeaderCollapsedIndicatorDirective, IgxHeaderExpandedIndicatorDirective, IgxHeadSelectorDirective, IgxHeadSelectorTemplateContext, IgxRowAddTextDirective, IgxRowCollapsedIndicatorDirective, IgxRowDirective, IgxRowDragGhostDirective, IgxRowEditActionsDirective, IgxRowEditTabStopDirective, IgxRowEditTemplateDirective, IgxRowEditTextDirective, IgxRowExpandedIndicatorDirective, IgxRowSelectorDirective, IgxRowSelectorTemplateContext, IgxSortAscendingHeaderIconDirective, IgxSortDescendingHeaderIconDirective, IgxSortHeaderIconDirective, IgxSummaryRowComponent, IgxToolbarToken, IPinColumnCancellableEventArgs, IPinColumnEventArgs, IPinningConfig, IPinRowEventArgs, IRowDataCancelableEventArgs, IRowDataEventArgs, IRowDragEndEventArgs, IRowDragStartEventArgs, IRowSelectionEventArgs, IRowToggleEventArgs, ISearchInfo, ISizeInfo, ISortingEventArgs, RowEditPositionStrategy, RowPinningPosition, RowType, WatchChanges } from 'igniteui-angular/grids/core';
111+
import { CharSeparatedValueData, DropPosition, FilterMode, getUUID, GridCellMergeMode, GridKeydownTargetType, GridPagingMode, GridSelectionMode, GridSelectionRange, GridServiceType, GridSummaryPosition, GridType, GridValidationTrigger, IActiveNode, IActiveNodeChangeEventArgs, ICellPosition, IClipboardOptions, IColumnMovingEndEventArgs, IColumnMovingEventArgs, IColumnMovingStartEventArgs, IColumnResizeEventArgs, IColumnsAutoGeneratedEventArgs, IColumnSelectionEventArgs, IColumnVisibilityChangedEventArgs, IColumnVisibilityChangingEventArgs, IFilteringEventArgs, IGridCellEventArgs, IGridClipboardEvent, IGridContextMenuEventArgs, IGridEditDoneEventArgs, IGridEditEventArgs, IGridFormGroupCreatedEventArgs, IGridKeydownEventArgs, IGridRowEventArgs, IGridScrollEventArgs, IGridToolbarExportEventArgs, IGridValidationStatusEventArgs, IGX_GRID_SERVICE_BASE, IgxAdvancedFilteringDialogComponent, IgxCell, IgxColumnComponent, IgxColumnGroupComponent, IgxColumnResizingService, IgxDragIndicatorIconDirective, IgxEditRow, IgxExcelStyleHeaderIconDirective, IgxExcelStyleLoadingValuesTemplateDirective, IgxFilteringService, IgxGridBodyDirective, IgxGridCellComponent, IgxGridColumnResizerComponent, IgxGridEmptyTemplateContext, IgxGridEmptyTemplateDirective, IgxGridExcelStyleFilteringComponent, IgxGridFilteringCellComponent, IgxGridFilteringRowComponent, IgxGridHeaderComponent, IgxGridHeaderGroupComponent, IgxGridHeaderRowComponent, IgxGridHeaderTemplateContext, IgxGridLoadingTemplateDirective, IgxGridNavigationService, IgxGridPinningActionsComponent, IgxGridRowDragGhostContext, IgxGridRowEditActionsTemplateContext, IgxGridRowEditTemplateContext, IgxGridRowEditTextTemplateContext, IgxGridRowTemplateContext, IgxGridSelectionService, IgxGridSummaryService, IgxGridTemplateContext, IgxGridToolbarComponent, IgxGridTransaction, IgxGridValidationService, IgxHeaderCollapsedIndicatorDirective, IgxHeaderExpandedIndicatorDirective, IgxHeadSelectorDirective, IgxHeadSelectorTemplateContext, IgxRowAddTextDirective, IgxRowCollapsedIndicatorDirective, IgxRowDirective, IgxRowDragGhostDirective, IgxRowEditActionsDirective, IgxRowEditTabStopDirective, IgxRowEditTemplateDirective, IgxRowEditTextDirective, IgxRowExpandedIndicatorDirective, IgxRowSelectorDirective, IgxRowSelectorTemplateContext, IgxSortAscendingHeaderIconDirective, IgxSortDescendingHeaderIconDirective, IgxSortHeaderIconDirective, IgxSummaryRowComponent, IgxToolbarToken, IPinColumnCancellableEventArgs, IPinColumnEventArgs, IPinningConfig, IPinRowEventArgs, IRowDataCancelableEventArgs, IRowDataEventArgs, IRowDragEndEventArgs, IRowDragStartEventArgs, IRowSelectionEventArgs, IRowToggleEventArgs, ISearchInfo, ISizeInfo, ISortingEventArgs, RowEditPositionStrategy, RowPinningPosition, RowType, WatchChanges } from 'igniteui-angular/grids/core';
112112
import { getCurrentI18n, getNumberFormatter, IResourceChangeEventArgs, } from 'igniteui-i18n-core';
113113
import { I18N_FORMATTER } from 'igniteui-angular/core';
114114

@@ -3666,7 +3666,7 @@ export abstract class IgxGridBaseDirective implements GridType,
36663666

36673667
protected getMergeCellOffset(rowData) {
36683668
const index = rowData.dataIndex;
3669-
let offset = this.verticalScrollContainer.scrollPosition - this.verticalScrollContainer.getScrollForIndex(index);
3669+
let offset = this.verticalScrollContainer._virtScrollPosition - this.verticalScrollContainer.getScrollForIndex(index);
36703670
if (this.hasPinnedRecords && this.isRowPinningToTop) {
36713671
offset -= this.pinnedRowHeight;
36723672
}
@@ -4071,6 +4071,13 @@ export abstract class IgxGridBaseDirective implements GridType,
40714071
this.paginationComponents.changes.pipe(takeUntil(this.destroy$)).subscribe(() => {
40724072
this.setUpPaginator();
40734073
});
4074+
4075+
this.actionStripComponents.changes.pipe(takeUntil(this.destroy$)).subscribe(() => {
4076+
if (this.actionStrip) {
4077+
this.actionStrip.menuOverlaySettings.outlet = this.outlet;
4078+
}
4079+
});
4080+
40744081
if (this.actionStrip) {
40754082
this.actionStrip.menuOverlaySettings.outlet = this.outlet;
40764083
}
@@ -7809,9 +7816,18 @@ export abstract class IgxGridBaseDirective implements GridType,
78097816
this.disableTransitions = false;
78107817

78117818
this.hideOverlays();
7812-
this.actionStrip?.hide();
7813-
if (this.actionStrip) {
7814-
this.actionStrip.context = null;
7819+
const context = this.actionStrip?.context;
7820+
const contextEl = context?.element?.nativeElement as HTMLElement;
7821+
const keepActionStrip =
7822+
!!context?.pinned &&
7823+
!!contextEl?.isConnected &&
7824+
!this.hasMenuPinningActions();
7825+
7826+
if (!keepActionStrip) {
7827+
if (this.actionStrip) {
7828+
this.actionStrip.hide();
7829+
this.actionStrip.context = null;
7830+
}
78157831
}
78167832
const args: IGridScrollEventArgs = {
78177833
direction: 'vertical',
@@ -7821,6 +7837,23 @@ export abstract class IgxGridBaseDirective implements GridType,
78217837
this.gridScroll.emit(args);
78227838
}
78237839

7840+
protected hasMenuPinningActions(): boolean {
7841+
const strip = this.actionStrip;
7842+
const actionButtons = strip?.actionButtons;
7843+
7844+
if (!actionButtons?.length) {
7845+
return false;
7846+
}
7847+
7848+
return actionButtons
7849+
.toArray()
7850+
.some(
7851+
(button) =>
7852+
button instanceof IgxGridPinningActionsComponent &&
7853+
button.asMenuItems
7854+
);
7855+
}
7856+
78247857
protected horizontalScrollHandler(event) {
78257858
const scrollLeft = event.target.scrollLeft;
78267859
this.headerContainer.onHScroll(scrollLeft);
@@ -8229,16 +8262,16 @@ export abstract class IgxGridBaseDirective implements GridType,
82298262
// recalc merged data
82308263
if (this.columnsToMerge.length > 0) {
82318264
const startIndex = this.verticalScrollContainer.state.startIndex;
8232-
const prevDataView = this.verticalScrollContainer.igxForOf?.slice(0, startIndex);
82338265
const data = [];
8234-
for (let index = 0; index < startIndex; index++) {
8235-
const rec = prevDataView[index];
8236-
if (rec.cellMergeMeta &&
8237-
// index + maxRowSpan is within view
8238-
startIndex < (index + Math.max(...rec.cellMergeMeta.values().toArray().map(x => x.rowSpan)))) {
8239-
const visibleIndex = this.isRowPinningToTop ? index + this.pinnedRecordsCount : index;
8240-
data.push({ record: rec, index: visibleIndex, dataIndex: index });
8241-
}
8266+
const rec = this.verticalScrollContainer.igxForOf[startIndex];
8267+
if (rec && rec.cellMergeMeta) {
8268+
this.columnsToMerge.forEach((col) => {
8269+
const root = rec.cellMergeMeta?.get(col.field)?.root;
8270+
if (root) {
8271+
data.push({ record: root, index: root.index, dataIndex: root.index });
8272+
}
8273+
})
8274+
82428275
}
82438276
this._mergedDataInView = data;
82448277
this.notifyChanges();

projects/igniteui-angular/grids/grid/src/grid.pipes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export class IgxGridUnmergeActivePipe implements PipeTransform {
121121

122122
const result = cloneArray(collection) as any;
123123
uniqueRoots.forEach(x => {
124-
const index = collection.indexOf(x);
124+
const index = x.index;
125125
const colKeys = [...x.cellMergeMeta.keys()];
126126
const cols = colsToMerge.filter(col => colKeys.indexOf(col.field) !== -1);
127127
for (const col of cols) {

projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,11 +424,12 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
424424
return this.parentIsland ? this.parentIsland.actionStrip : super.actionStrip;
425425
}
426426

427+
/** @hidden @internal */
427428
/* blazorCSSuppress */
428429
public override get advancedFilteringExpressionsTree(): IFilteringExpressionsTree {
429430
return super.advancedFilteringExpressionsTree;
430431
}
431-
432+
/** @hidden @internal */
432433
public override set advancedFilteringExpressionsTree(value: IFilteringExpressionsTree) {
433434
if (!this._hGridSchema) {
434435
this._hGridSchema = this.generateSchema();

0 commit comments

Comments
 (0)