Skip to content

Commit 8a87a4c

Browse files
authored
Merge pull request #7574 from IgniteUI/pbozhinov/fix-5673-10
Deselect Row on Transaction Redo
2 parents 8f1c49b + 8bf691f commit 8a87a4c

File tree

7 files changed

+103
-33
lines changed

7 files changed

+103
-33
lines changed

CHANGELOG.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
# Ignite UI for Angular Change Log
22

33
All notable changes for each version of this project will be documented in this file.
4-
## 10.0.0
5-
6-
### New Features
7-
8-
- `IgxGrid`
9-
- `showGroupArea` input is added, which can be used to enable/disable the group area row.
104

11-
## 10.0
5+
## 10.0.0
126

137
### General
148
- `igx-select`, `igx-combo`, `igx-drop-down`
159
- **Behavioral Change** - The select, combo, and dropdown items now have display block and text-overflow ellipsis enabled by default.
10+
- `IgxTransaction` - The `onStateUpdate` now emits with information of its origin. The emitted value is of type `StateUpdateEvent`, which has two properties:
11+
- `origin` - it can vary within the values of the `TransactionEventOrigin` interface;
12+
- `actions` - contains information about the transactions, that caused the emission of the event.
13+
14+
### New Features
15+
- `IgxGrid`
16+
- `showGroupArea` input is added, which can be used to enable/disable the group area row.
1617

1718
## 9.1.1
1819

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ import {
4646
OverlaySettings,
4747
PositionSettings,
4848
ConnectedPositioningStrategy,
49-
ContainerPositionStrategy
49+
ContainerPositionStrategy,
50+
StateUpdateEvent,
51+
TransactionEventOrigin
5052
} from '../services/public_api';
5153
import { GridBaseAPIService } from './api.service';
5254
import { IgxGridCellComponent } from './cell.component';
@@ -2856,7 +2858,20 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements
28562858
this.summaryService.clearSummaryCache(args);
28572859
});
28582860

2859-
this.transactions.onStateUpdate.pipe(destructor).subscribe(() => {
2861+
this.transactions.onStateUpdate.pipe(destructor).subscribe((event: StateUpdateEvent) => {
2862+
let actions = [];
2863+
if (event.origin === TransactionEventOrigin.REDO) {
2864+
actions = event.actions ? event.actions.filter(x => x.transaction.type === TransactionType.DELETE) : [];
2865+
} else if (event.origin === TransactionEventOrigin.UNDO) {
2866+
actions = event.actions ? event.actions.filter(x => x.transaction.type === TransactionType.ADD) : [];
2867+
}
2868+
if (actions.length > 0) {
2869+
for (const action of actions) {
2870+
if (this.selectionService.isRowSelected(action.transaction.id)) {
2871+
this.selectionService.deselectRow(action.transaction.id);
2872+
}
2873+
}
2874+
}
28602875
this.selectionService.clearHeaderCBState();
28612876
this.summaryService.clearSummaryCache();
28622877
this._pipeTrigger++;

projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-selection.spec.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,6 @@ describe('IgxTreeGrid - Selection #tGrid', () => {
490490
}));
491491

492492
it('should deselect row when delete its parent', () => {
493-
pending('Related to the bug #5673');
494493
treeGrid.selectRows([treeGrid.getRowByIndex(3).rowID, treeGrid.getRowByIndex(5).rowID], true);
495494
fix.detectChanges();
496495

@@ -506,8 +505,8 @@ describe('IgxTreeGrid - Selection #tGrid', () => {
506505
expect(treeGrid.selectedRows()).toEqual([]);
507506

508507
// try to select deleted row
509-
TreeGridFunctions.clickRowSelectionCheckbox(fix, 0);
510-
UIInteractions.simulateClickEvent(treeGrid.getRowByIndex(3).nativeElement);
508+
UIInteractions.simulateClickEvent(treeGrid.getRowByIndex(0).nativeElement);
509+
TreeGridFunctions.clickRowSelectionCheckbox(fix, 3);
511510
TreeGridFunctions.clickRowSelectionCheckbox(fix, 5);
512511
fix.detectChanges();
513512

@@ -522,8 +521,8 @@ describe('IgxTreeGrid - Selection #tGrid', () => {
522521
fix.detectChanges();
523522

524523
// select rows
525-
TreeGridFunctions.clickRowSelectionCheckbox(fix, 0);
526-
UIInteractions.simulateClickEvent(treeGrid.getRowByIndex(3).nativeElement);
524+
UIInteractions.simulateClickEvent(treeGrid.getRowByIndex(0).nativeElement);
525+
TreeGridFunctions.clickRowSelectionCheckbox(fix, 3);
527526
TreeGridFunctions.clickRowSelectionCheckbox(fix, 5);
528527
fix.detectChanges();
529528

@@ -579,7 +578,6 @@ describe('IgxTreeGrid - Selection #tGrid', () => {
579578
});
580579

581580
it('should have correct header checkbox when add a row', () => {
582-
pending('Related to the bug #5673');
583581
treeGrid.selectAllRows();
584582
fix.detectChanges();
585583

@@ -600,7 +598,6 @@ describe('IgxTreeGrid - Selection #tGrid', () => {
600598
});
601599

602600
it('should have correct header checkbox when add a row and undo transaction', fakeAsync(() => {
603-
pending('Related to the bug #5673');
604601
treeGrid.addRow({ ID: 13, Name: 'Michael Cooper', Age: 33, OnPTO: false }, 317);
605602
tick();
606603
fix.detectChanges();

projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@ import { IgxGridBaseDirective } from '../grid-base.directive';
1717
import { GridBaseAPIService } from '../api.service';
1818
import { ITreeGridRecord } from './tree-grid.interfaces';
1919
import { IRowToggleEventArgs } from '../common/events';
20-
import { HierarchicalTransaction, HierarchicalState, TransactionType } from '../../services/transaction/transaction';
20+
import {
21+
HierarchicalTransaction,
22+
HierarchicalState,
23+
TransactionType,
24+
TransactionEventOrigin,
25+
StateUpdateEvent
26+
} from '../../services/transaction/transaction';
2127
import { IgxHierarchicalTransactionService } from '../../services/public_api';
2228
import { IgxFilteringService } from '../filtering/grid-filtering.service';
2329
import { IgxGridSummaryService } from '../summaries/grid-summary.service';
@@ -30,6 +36,7 @@ import { IgxGridNavigationService } from '../grid-navigation.service';
3036
import { GridType } from '../common/grid.interface';
3137
import { IgxColumnComponent } from '../columns/column.component';
3238
import { IgxRowIslandAPIService } from '../hierarchical-grid/row-island-api.service';
39+
import { IgxTreeGridRowComponent } from './tree-grid-row.component';
3340

3441
let NEXT_ID = 0;
3542

@@ -345,6 +352,20 @@ export class IgxTreeGridComponent extends IgxGridBaseDirective implements GridTy
345352
this.onRowToggle.pipe(takeUntil(this.destroy$)).subscribe((args) => {
346353
this.loadChildrenOnRowExpansion(args);
347354
});
355+
356+
this.transactions.onStateUpdate.pipe(takeUntil<any>(this.destroy$)).subscribe((event: StateUpdateEvent) => {
357+
let actions = [];
358+
if (event.origin === TransactionEventOrigin.REDO) {
359+
actions = event.actions ? event.actions.filter(x => x.transaction.type === TransactionType.DELETE) : [];
360+
} else if (event.origin === TransactionEventOrigin.UNDO) {
361+
actions = event.actions ? event.actions.filter(x => x.transaction.type === TransactionType.ADD) : [];
362+
}
363+
if (actions.length) {
364+
for (const action of actions) {
365+
this.deselectChildren(action.transaction.id);
366+
}
367+
}
368+
});
348369
}
349370

350371
ngDoCheck() {
@@ -663,4 +684,20 @@ export class IgxTreeGridComponent extends IgxGridBaseDirective implements GridTy
663684
}
664685
super.initColumns(collection, cb);
665686
}
687+
688+
/**
689+
* @description A recursive way to deselect all selected children of a given record
690+
* @param recordID ID of the record whose children to deselect
691+
* @hidden
692+
* @internal
693+
*/
694+
private deselectChildren(recordID): void {
695+
const selectedChildren = [];
696+
const rowToDeselect = (this.getRowByKey(recordID) as IgxTreeGridRowComponent).treeRow;
697+
this.selectionService.deselectRow(recordID);
698+
this._gridAPI.get_selected_children(rowToDeselect, selectedChildren);
699+
if (selectedChildren.length > 0) {
700+
selectedChildren.forEach(x => this.deselectChildren(x));
701+
}
702+
}
666703
}

projects/igniteui-angular/src/lib/services/transaction/base-transaction.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TransactionService, Transaction, State } from './transaction';
1+
import { TransactionService, Transaction, State, StateUpdateEvent } from './transaction';
22
import { EventEmitter, Injectable } from '@angular/core';
33
import { isObject, mergeObjects, cloneValue } from '../../core/utils';
44

@@ -32,7 +32,7 @@ export class IgxBaseTransactionService<T extends Transaction, S extends State> i
3232
/**
3333
* @inheritdoc
3434
*/
35-
public onStateUpdate = new EventEmitter<void>();
35+
public onStateUpdate = new EventEmitter<StateUpdateEvent>();
3636

3737
/**
3838
* @inheritdoc

projects/igniteui-angular/src/lib/services/transaction/igx-transaction.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { Transaction, State, TransactionType } from './transaction';
1+
import { Transaction, State, TransactionType, StateUpdateEvent, TransactionEventOrigin, Action } from './transaction';
22
import { IgxBaseTransactionService } from './base-transaction';
33
import { EventEmitter, Injectable } from '@angular/core';
44
import { isObject, mergeObjects, cloneValue } from '../../core/utils';
55

66
@Injectable()
77
export class IgxTransactionService<T extends Transaction, S extends State> extends IgxBaseTransactionService<T, S> {
88
protected _transactions: T[] = [];
9-
protected _redoStack: { transaction: T, recordRef: any }[][] = [];
10-
protected _undoStack: { transaction: T, recordRef: any }[][] = [];
9+
protected _redoStack: Action<T>[][] = [];
10+
protected _undoStack: Action<T>[][] = [];
1111
protected _states: Map<any, S> = new Map();
1212

1313
/**
@@ -27,7 +27,7 @@ export class IgxTransactionService<T extends Transaction, S extends State> exten
2727
/**
2828
* @inheritdoc
2929
*/
30-
public onStateUpdate = new EventEmitter<void>();
30+
public onStateUpdate = new EventEmitter<StateUpdateEvent>();
3131

3232
/**
3333
* @inheritdoc
@@ -45,9 +45,10 @@ export class IgxTransactionService<T extends Transaction, S extends State> exten
4545
transactions.push(transaction);
4646

4747
if (!this._isPending) {
48-
this._undoStack.push([{ transaction, recordRef }]);
48+
const actions = [{ transaction, recordRef }];
49+
this._undoStack.push(actions);
4950
this._redoStack = [];
50-
this.onStateUpdate.emit();
51+
this.onStateUpdate.emit({ origin: TransactionEventOrigin.ADD, actions });
5152
}
5253
}
5354

@@ -115,7 +116,7 @@ export class IgxTransactionService<T extends Transaction, S extends State> exten
115116
public endPending(commit: boolean): void {
116117
this._isPending = false;
117118
if (commit) {
118-
const actions: { transaction: T, recordRef: any }[] = [];
119+
const actions: Action<T>[] = [];
119120
// don't use addTransaction due to custom undo handling
120121
for (const transaction of this._pendingTransactions) {
121122
const pendingState = this._pendingStates.get(transaction.id);
@@ -127,7 +128,7 @@ export class IgxTransactionService<T extends Transaction, S extends State> exten
127128
this._undoStack.push(actions);
128129
this._redoStack = [];
129130

130-
this.onStateUpdate.emit();
131+
this.onStateUpdate.emit({ origin: TransactionEventOrigin.END, actions});
131132
}
132133
super.endPending(commit);
133134
}
@@ -167,7 +168,7 @@ export class IgxTransactionService<T extends Transaction, S extends State> exten
167168
this._undoStack = [];
168169
}
169170
this._redoStack = [];
170-
this.onStateUpdate.emit();
171+
this.onStateUpdate.emit({ origin: TransactionEventOrigin.CLEAR, actions: []});
171172
}
172173

173174
/**
@@ -178,7 +179,7 @@ export class IgxTransactionService<T extends Transaction, S extends State> exten
178179
return;
179180
}
180181

181-
const lastActions: { transaction: T, recordRef: any }[] = this._undoStack.pop();
182+
const lastActions: Action<T>[] = this._undoStack.pop();
182183
this._transactions.splice(this._transactions.length - lastActions.length);
183184
this._redoStack.push(lastActions);
184185

@@ -189,23 +190,23 @@ export class IgxTransactionService<T extends Transaction, S extends State> exten
189190
}
190191
}
191192

192-
this.onStateUpdate.emit();
193+
this.onStateUpdate.emit({ origin: TransactionEventOrigin.UNDO, actions: lastActions });
193194
}
194195

195196
/**
196197
* @inheritdoc
197198
*/
198199
public redo(): void {
199200
if (this._redoStack.length > 0) {
200-
let actions: { transaction: T, recordRef: any, useInUndo?: boolean }[];
201+
let actions: Action<T>[];
201202
actions = this._redoStack.pop();
202203
for (const action of actions) {
203204
this.updateState(this._states, action.transaction, action.recordRef);
204205
this._transactions.push(action.transaction);
205206
}
206207

207208
this._undoStack.push(actions);
208-
this.onStateUpdate.emit();
209+
this.onStateUpdate.emit({ origin: TransactionEventOrigin.REDO, actions });
209210
}
210211
}
211212

projects/igniteui-angular/src/lib/services/transaction/transaction.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
import { EventEmitter } from '@angular/core';
2+
import { ThrowStmt } from '@angular/compiler';
23

34
export enum TransactionType {
45
ADD = 'add',
56
DELETE = 'delete',
67
UPDATE = 'update'
78
}
89

10+
export enum TransactionEventOrigin {
11+
UNDO = 'undo',
12+
REDO = 'redo',
13+
CLEAR = 'clear',
14+
ADD = 'add',
15+
END = 'endPending'
16+
}
17+
918
export interface Transaction {
1019
id: any;
1120
type: TransactionType;
@@ -26,6 +35,16 @@ export interface State {
2635
type: TransactionType;
2736
}
2837

38+
export interface Action<T extends Transaction> {
39+
transaction: T;
40+
recordRef: any;
41+
}
42+
43+
export interface StateUpdateEvent {
44+
origin: TransactionEventOrigin;
45+
actions: Action<Transaction>[];
46+
}
47+
2948
/**
3049
* @experimental
3150
* @hidden
@@ -43,7 +62,7 @@ export interface TransactionService<T extends Transaction, S extends State> {
4362
/**
4463
* Event fired when transaction state has changed - add transaction, commit all transactions, undo and redo
4564
*/
46-
onStateUpdate?: EventEmitter<void>;
65+
onStateUpdate?: EventEmitter<StateUpdateEvent>;
4766

4867
/**
4968
* @returns if there are any transactions in the Undo stack

0 commit comments

Comments
 (0)