@@ -31,7 +31,7 @@ import {
31
31
} from '@angular/core' ;
32
32
import { resizeObservable } from '../core/utils' ;
33
33
import 'igniteui-trial-watermark' ;
34
- import { Subject , pipe , fromEvent , animationFrameScheduler } from 'rxjs' ;
34
+ import { Subject , pipe , fromEvent , animationFrameScheduler , merge } from 'rxjs' ;
35
35
import { takeUntil , first , filter , throttleTime , map , shareReplay , takeWhile } from 'rxjs/operators' ;
36
36
import { cloneArray , mergeObjects , compareMaps , resolveNestedPath , isObject , PlatformUtil } from '../core/utils' ;
37
37
import { GridColumnDataType } from '../data-operations/data-util' ;
@@ -50,7 +50,8 @@ import {
50
50
ConnectedPositioningStrategy ,
51
51
ContainerPositionStrategy ,
52
52
StateUpdateEvent ,
53
- TransactionEventOrigin
53
+ TransactionEventOrigin ,
54
+ Action ,
54
55
} from '../services/public_api' ;
55
56
import { GridBaseAPIService } from './api.service' ;
56
57
import { IgxGridCellComponent } from './cell.component' ;
@@ -154,6 +155,7 @@ import { IPageEventArgs } from '../paginator/paginator-interfaces';
154
155
import { IgxPaginatorComponent } from '../paginator/paginator.component' ;
155
156
import { IgxGridHeaderRowComponent } from './headers/grid-header-row.component' ;
156
157
import { IgxGridGroupByAreaComponent } from './grouping/grid-group-by-area.component' ;
158
+ import { IgxFlatTransactionFactory , TRANSACTION_TYPE } from '../services/transaction/transaction-factory.service' ;
157
159
158
160
let FAKE_ROW_ID = - 1 ;
159
161
const DEFAULT_ITEMS_PER_PAGE = 15 ;
@@ -171,6 +173,7 @@ export const IgxGridTransaction = new InjectionToken<string>('IgxGridTransaction
171
173
@Directive ( )
172
174
export abstract class IgxGridBaseDirective extends DisplayDensityBase implements GridType ,
173
175
OnInit , DoCheck , OnDestroy , AfterContentInit , AfterViewInit {
176
+
174
177
/**
175
178
* Gets/Sets the display time for the row adding snackbar notification.
176
179
*
@@ -2365,6 +2368,31 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
2365
2368
this . notifyChanges ( ) ;
2366
2369
}
2367
2370
2371
+ /**
2372
+ * Gets/Sets whether the grid has batch editing enabled.
2373
+ * When batch editing is enabled, changes are not made directly to the underlying data.
2374
+ * Instead, they are stored as transactions, which can later be committed w/ the `commit` method.
2375
+ *
2376
+ * @example
2377
+ * ```html
2378
+ * <igx-grid [batchEditing]="true" [data]="someData">
2379
+ * </igx-grid>
2380
+ * ```
2381
+ */
2382
+ @Input ( )
2383
+ public get batchEditing ( ) : boolean {
2384
+ return this . _batchEditing ;
2385
+ }
2386
+
2387
+ public set batchEditing ( val : boolean ) {
2388
+ if ( val !== this . _batchEditing ) {
2389
+ delete this . _transactions ;
2390
+ this . _batchEditing = val ;
2391
+ this . switchTransactionService ( val ) ;
2392
+ this . subscribeToTransactions ( ) ;
2393
+ }
2394
+ }
2395
+
2368
2396
/** @hidden @internal */
2369
2397
public get pinnedColumnsTextInternal ( ) {
2370
2398
return this . _pinnedColumnsText ;
@@ -2374,6 +2402,9 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
2374
2402
* Get transactions service for the grid.
2375
2403
*/
2376
2404
public get transactions ( ) : TransactionService < Transaction , State > {
2405
+ if ( this . _diTransactions && ! this . batchEditing ) {
2406
+ return this . _diTransactions ;
2407
+ }
2377
2408
return this . _transactions ;
2378
2409
}
2379
2410
@@ -2825,6 +2856,8 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
2825
2856
protected _init = true ;
2826
2857
protected _cdrRequestRepaint = false ;
2827
2858
protected _userOutletDirective : IgxOverlayOutletDirective ;
2859
+ protected _transactions : TransactionService < Transaction , State > ;
2860
+ protected _batchEditing = false ;
2828
2861
2829
2862
/** @hidden @internal */
2830
2863
public get paginator ( ) {
@@ -2928,6 +2961,8 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
2928
2961
positionStrategy : this . rowEditPositioningStrategy
2929
2962
} ;
2930
2963
2964
+ private transactionChange$ = new Subject < void > ( ) ;
2965
+
2931
2966
private readonly DRAG_SCROLL_DELTA = 10 ;
2932
2967
2933
2968
/**
@@ -3056,7 +3091,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
3056
3091
public selectionService : IgxGridSelectionService ,
3057
3092
public colResizingService : IgxColumnResizingService ,
3058
3093
public gridAPI : GridBaseAPIService < IgxGridBaseDirective & GridType > ,
3059
- @ Inject ( IgxGridTransaction ) protected _transactions : TransactionService < Transaction , State > ,
3094
+ protected transactionFactory : IgxFlatTransactionFactory ,
3060
3095
private elementRef : ElementRef < HTMLElement > ,
3061
3096
private zone : NgZone ,
3062
3097
@Inject ( DOCUMENT ) public document : any ,
@@ -3070,13 +3105,15 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
3070
3105
public summaryService : IgxGridSummaryService ,
3071
3106
@Optional ( ) @Inject ( DisplayDensityToken ) protected _displayDensityOptions : IDisplayDensityOptions ,
3072
3107
@Inject ( LOCALE_ID ) private localeId : string ,
3073
- protected platform : PlatformUtil ) {
3108
+ protected platform : PlatformUtil ,
3109
+ @Optional ( ) @Inject ( IgxGridTransaction ) protected _diTransactions ?: TransactionService < Transaction , State > ) {
3074
3110
super ( _displayDensityOptions ) ;
3075
3111
this . locale = this . locale || this . localeId ;
3076
3112
this . datePipe = new DatePipe ( this . locale ) ;
3077
3113
this . decimalPipe = new DecimalPipe ( this . locale ) ;
3078
3114
this . currencyPipe = new CurrencyPipe ( this . locale ) ;
3079
3115
this . percentPipe = new PercentPipe ( this . locale ) ;
3116
+ this . _transactions = this . transactionFactory . create ( TRANSACTION_TYPE . None ) ;
3080
3117
this . cdr . detach ( ) ;
3081
3118
}
3082
3119
@@ -3289,25 +3326,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
3289
3326
this . summaryService . clearSummaryCache ( args ) ;
3290
3327
} ) ;
3291
3328
3292
- this . transactions . onStateUpdate . pipe ( destructor ) . subscribe ( ( event : StateUpdateEvent ) => {
3293
- let actions = [ ] ;
3294
- if ( event . origin === TransactionEventOrigin . REDO ) {
3295
- actions = event . actions ? event . actions . filter ( x => x . transaction . type === TransactionType . DELETE ) : [ ] ;
3296
- } else if ( event . origin === TransactionEventOrigin . UNDO ) {
3297
- actions = event . actions ? event . actions . filter ( x => x . transaction . type === TransactionType . ADD ) : [ ] ;
3298
- }
3299
- if ( actions . length > 0 ) {
3300
- for ( const action of actions ) {
3301
- if ( this . selectionService . isRowSelected ( action . transaction . id ) ) {
3302
- this . selectionService . deselectRow ( action . transaction . id ) ;
3303
- }
3304
- }
3305
- }
3306
- this . selectionService . clearHeaderCBState ( ) ;
3307
- this . summaryService . clearSummaryCache ( ) ;
3308
- this . pipeTrigger ++ ;
3309
- this . notifyChanges ( ) ;
3310
- } ) ;
3329
+ this . subscribeToTransactions ( ) ;
3311
3330
3312
3331
this . resizeNotify . pipe (
3313
3332
destructor ,
@@ -3688,6 +3707,8 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
3688
3707
3689
3708
this . destroy$ . next ( true ) ;
3690
3709
this . destroy$ . complete ( ) ;
3710
+ this . transactionChange$ . next ( ) ;
3711
+ this . transactionChange$ . complete ( ) ;
3691
3712
this . _destroyed = true ;
3692
3713
3693
3714
if ( this . _advancedFilteringOverlayId ) {
@@ -4283,6 +4304,14 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
4283
4304
* ```
4284
4305
*/
4285
4306
public moveColumn ( column : IgxColumnComponent , target : IgxColumnComponent , pos : DropPosition = DropPosition . AfterDropTarget ) {
4307
+ // M.A. May 11th, 2021 #9508 Make the event cancelable
4308
+ const eventArgs : IColumnMovingEndEventArgs = { source : column , target, cancel : false } ;
4309
+
4310
+ this . columnMovingEnd . emit ( eventArgs ) ;
4311
+
4312
+ if ( eventArgs . cancel ) {
4313
+ return ;
4314
+ }
4286
4315
4287
4316
if ( column === target || ( column . level !== target . level ) ||
4288
4317
( column . topLevelParent !== target . topLevelParent ) ) {
@@ -4318,8 +4347,6 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
4318
4347
4319
4348
this . _moveColumns ( column , target , pos ) ;
4320
4349
this . _columnsReordered ( column ) ;
4321
-
4322
- this . columnMovingEnd . emit ( { source : column , target } ) ;
4323
4350
}
4324
4351
4325
4352
/**
@@ -5996,6 +6023,40 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
5996
6023
this . crudService . endEdit ( commit , event ) ;
5997
6024
}
5998
6025
6026
+ protected switchTransactionService ( val : boolean ) {
6027
+ if ( val ) {
6028
+ this . _transactions = this . transactionFactory . create ( TRANSACTION_TYPE . Base ) ;
6029
+ } else {
6030
+ this . _transactions = this . transactionFactory . create ( TRANSACTION_TYPE . None ) ;
6031
+ }
6032
+ }
6033
+
6034
+ protected subscribeToTransactions ( ) : void {
6035
+ this . transactionChange$ . next ( ) ;
6036
+ this . transactions . onStateUpdate . pipe ( takeUntil ( merge ( this . destroy$ , this . transactionChange$ ) ) )
6037
+ . subscribe ( this . transactionStatusUpdate . bind ( this ) ) ;
6038
+ }
6039
+
6040
+ protected transactionStatusUpdate ( event : StateUpdateEvent ) {
6041
+ let actions : Action < Transaction > [ ] = [ ] ;
6042
+ if ( event . origin === TransactionEventOrigin . REDO ) {
6043
+ actions = event . actions ? event . actions . filter ( x => x . transaction . type === TransactionType . DELETE ) : [ ] ;
6044
+ } else if ( event . origin === TransactionEventOrigin . UNDO ) {
6045
+ actions = event . actions ? event . actions . filter ( x => x . transaction . type === TransactionType . ADD ) : [ ] ;
6046
+ }
6047
+ if ( actions . length > 0 ) {
6048
+ for ( const action of actions ) {
6049
+ if ( this . selectionService . isRowSelected ( action . transaction . id ) ) {
6050
+ this . selectionService . deselectRow ( action . transaction . id ) ;
6051
+ }
6052
+ }
6053
+ }
6054
+ this . selectionService . clearHeaderCBState ( ) ;
6055
+ this . summaryService . clearSummaryCache ( ) ;
6056
+ this . pipeTrigger ++ ;
6057
+ this . notifyChanges ( ) ;
6058
+ } ;
6059
+
5999
6060
protected writeToData ( rowIndex : number , value : any ) {
6000
6061
mergeObjects ( this . gridAPI . get_all_data ( ) [ rowIndex ] , value ) ;
6001
6062
}
0 commit comments