Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

igxTreeGrid batch update, #2921 #2954

Merged
merged 103 commits into from
Dec 7, 2018
Merged
Show file tree
Hide file tree
Changes from 97 commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
79c995e
refactor(tree-grid): remove unused methods and classes, #2921
wnvko Nov 7, 2018
cc9e33d
refactor(tree-grid): apply transaction in one iteration, #2921
wnvko Nov 7, 2018
03db459
chore(tree-grid): add missed sample component
wnvko Nov 7, 2018
5781a74
chore(tree-grid): remove console.log from tree-grid.pipes
wnvko Nov 7, 2018
48cbb61
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
7bd14de
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
a75f947
chore(tree-grid): remove call to missing field in igx-transaction
wnvko Nov 13, 2018
1b479be
refactor(tree-grid): apply transaction in one iteration, #2921
wnvko Nov 7, 2018
9f40364
chore(tree-grid): remove console.log from tree-grid.pipes
wnvko Nov 7, 2018
92901bf
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
baba9d8
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
ba91d22
chore(tree-grid): remove call to missing field in igx-transaction
wnvko Nov 13, 2018
6a19081
test(tree-grid): fix failing test in transactions, #2921
wnvko Nov 13, 2018
0a0dcfe
feat(tree-grid): update states in hierarchical data, #2921
wnvko Nov 13, 2018
1302816
feat(tree-grid): hierarchical transaction are in stable state now, #2921
wnvko Nov 14, 2018
4c10e24
refactor(tree-grid): apply transaction in one iteration, #2921
wnvko Nov 7, 2018
eccd29d
chore(tree-grid): remove console.log from tree-grid.pipes
wnvko Nov 7, 2018
3097fad
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
cd4f61d
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
5c02658
chore(tree-grid): remove call to missing field in igx-transaction
wnvko Nov 13, 2018
6330529
refactor(tree-grid): apply transaction in one iteration, #2921
wnvko Nov 7, 2018
377a13a
chore(tree-grid): remove console.log from tree-grid.pipes
wnvko Nov 7, 2018
d61d253
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
dfc3a11
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
2cf2743
chore(tree-grid): remove call to missing field in igx-transaction
wnvko Nov 13, 2018
e501142
feat(tree-grid): update states in hierarchical data, #2921
wnvko Nov 13, 2018
db5fd4e
refactor(tree-grid): apply transaction in one iteration, #2921
wnvko Nov 7, 2018
fa88cb0
chore(tree-grid): remove console.log from tree-grid.pipes
wnvko Nov 7, 2018
432b928
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
4a1be53
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
d7e790b
chore(tree-grid): remove call to missing field in igx-transaction
wnvko Nov 13, 2018
c955cc3
refactor(tree-grid): apply transaction in one iteration, #2921
wnvko Nov 7, 2018
4e4994a
chore(tree-grid): remove console.log from tree-grid.pipes
wnvko Nov 7, 2018
4477dcb
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
71cc6d6
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
dce642b
chore(tree-grid): remove call to missing field in igx-transaction
wnvko Nov 13, 2018
5c5ce80
refactor(tree-grid): apply transaction in one iteration, #2921
wnvko Nov 7, 2018
a5c5349
chore(tree-grid): remove console.log from tree-grid.pipes
wnvko Nov 7, 2018
9375ed7
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
60d4bb8
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
8b7f90e
chore(tree-grid): remove call to missing field in igx-transaction
wnvko Nov 13, 2018
24b0687
refactor(tree-grid): apply transaction in one iteration, #2921
wnvko Nov 7, 2018
c357207
chore(tree-grid): remove console.log from tree-grid.pipes
wnvko Nov 7, 2018
27c36fc
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
d5bbcaa
feat(tree-grid): update flat data transaction, #2921
wnvko Nov 13, 2018
5d89ef6
chore(tree-grid): remove call to missing field in igx-transaction
wnvko Nov 13, 2018
388762d
fix(tree-grid): fix circular reference exception. #2921
wnvko Nov 14, 2018
a5352d5
refactor(tree-grid): update mergeTransactions static method
wnvko Nov 19, 2018
825d54a
fix(tree-grid): delete row in flat data source, #2921
wnvko Nov 19, 2018
c044d4a
fix(tree-grid): update cell in hierarchical grid with row edit, #2921
wnvko Nov 19, 2018
dcd8a18
refactor(tree-grid): change endRowTransaction to call endPending once…
wnvko Nov 19, 2018
77e5f91
fix(tree-grid): allow deletion of add root row, #2921
wnvko Nov 19, 2018
e5faf60
test(row-editing): Adding test scenarios #2921
dafo Nov 19, 2018
2630d01
test(row-editing): Adding more scenarios ##2921
dafo Nov 19, 2018
6e274be
refactor(tree-grid): sample add root row may add several rows now
wnvko Nov 19, 2018
b8494f5
test(IgxTreeGrid): Adding flat data delete row tests. #2921
PlamenaMiteva Nov 20, 2018
df2169a
test(IgxTreeGrid): Adding RowEditingTransactionComponent. #2921
IvayloG Nov 20, 2018
51b67c5
test(IgxTreeGrid): Adding test. #2921
IvayloG Nov 20, 2018
2141c79
test(IgxTreeGrid): Adding test. #2921
IvayloG Nov 20, 2018
dda7c42
test(IgxTreeGrid): Adding test. #2921
IvayloG Nov 20, 2018
e6f81da
chore(row=editing): Adding a template with Hierarchical DS #2921
dafo Nov 20, 2018
937d2a2
test(IgxTreeGrid): Adding hierarchical data delete row tests. #2921
PlamenaMiteva Nov 20, 2018
ce05f24
chore(IgxTreeGrid): Add TreeGridintegration tests
PlamenaMiteva Nov 8, 2018
9bcd010
chore(igxTreeGrid): update imports, use proper transaction service
ViktorSlavov Nov 20, 2018
81d0f99
test(IgxTreeGrid): Adding test. #2921
IvayloG Nov 20, 2018
b497a3f
fix(tree-grid): allow edit of ADD row, #2921
wnvko Nov 20, 2018
20fe3d4
chore(igxTreeGrid): add test for UNDO/REDO
ViktorSlavov Nov 20, 2018
bfc1a49
chore(igxTreeGrid): fix lint error in spec file
ViktorSlavov Nov 20, 2018
9098a78
chore(IgxTreeGrid): Remove fit. #2921
IvayloG Nov 20, 2018
2beff83
test(IgxTreeGrid): Adding test. #2921
IvayloG Nov 21, 2018
0bd0eed
test(IgxTreeGrid): Adding empty ChildDataKey test. #2921
IvayloG Nov 21, 2018
0f4542a
fix(tree-grid): edit added row with rowEdit=true, #2921
wnvko Nov 21, 2018
8b427c7
chore(igxTreeGrid): fix failing tests
ViktorSlavov Nov 21, 2018
da2e58e
chore(IgxTreeGrid): Remove test, add Batch Editing describe. #2921
IvayloG Nov 21, 2018
60af885
fix(tree-grid): add row with transactions to empty grid, #2921
wnvko Nov 21, 2018
5079475
test(tree-grid): add empty grid test scenarios, #2921
wnvko Nov 21, 2018
3950887
refactor(tree-grid): remove path from ITreeGridRecord
wnvko Nov 22, 2018
7c0c166
test(tree-grid): add more test for hierarchical transaction, #2921
wnvko Nov 22, 2018
1016d3e
refactor(tree-grid): fix alphabetical order of components in dev demos
wnvko Nov 22, 2018
8445cab
test(tree-grid): test add parent node to a Hierarchical DS tree grid,…
PlamenaMiteva Nov 21, 2018
0fc7d4f
test(IgxTreeGrid): Adding rows to empty data grid tests. #2921
IvayloG Nov 21, 2018
dc360a4
test(tree-grid): merge transactions tests add, #2921
wnvko Nov 22, 2018
1d5ab29
refactor(tree-grid): fix tslint errors
wnvko Nov 22, 2018
c926efd
test(igxTreeGrid): whatever I put here Damian will squash it, #2921
wnvko Dec 5, 2018
7860912
Merge branch 'master' into mvenkov/tree-grid-batch-update
wnvko Dec 5, 2018
dedbd3e
Merge branch 'master' into mvenkov/tree-grid-batch-update
wnvko Dec 6, 2018
c617527
refactor(igxTreeGrid): do not change path during transaction merge
wnvko Dec 6, 2018
e7c973a
Merge branch 'master' into mvenkov/tree-grid-batch-update
wnvko Dec 6, 2018
b7d28dd
refactor(igxTreeGrid): remove path splice in merge, #2921
wnvko Dec 6, 2018
5fda341
refactor(igxTreeGrid): update mergeHierarchicalTransaction, #2921
wnvko Dec 6, 2018
c694bca
Merge branch 'master' into mvenkov/tree-grid-batch-update
wnvko Dec 6, 2018
90add5c
chore(igxTreeGrid): remove commented rows, #2921
wnvko Dec 6, 2018
d5e1b2a
Merge branch 'master' into mvenkov/tree-grid-batch-update
wnvko Dec 6, 2018
867588c
chore(igxTreGeid): update CHANGELOG.md, #2921
wnvko Dec 7, 2018
8422d08
refactor(igxTreeGrid): make deleteRowById protected and refactor it, …
wnvko Dec 7, 2018
bd37cbe
Merge remote-tracking branch 'remotes/origin/master' into mvenkov/tre…
wnvko Dec 7, 2018
98d2a57
chore(igxTreeGrid): fix after merge errors, #2921
wnvko Dec 7, 2018
ae0683b
refactor(igxTreeGrid): switch array.map to for-of, #2921
wnvko Dec 7, 2018
39fa460
refactor(igxTreeGrid): switch array.map and for loops with for-of, #2921
wnvko Dec 7, 2018
1dd790a
Merge branch 'mvenkov/tree-grid-batch-update' of https://github.com/I…
wnvko Dec 7, 2018
e537808
Merge remote-tracking branch 'remotes/origin/master' into mvenkov/tre…
wnvko Dec 7, 2018
60ab88d
chore(igxTreeGrid): switch back from ChromeHeadless to Chrome, #2921
wnvko Dec 7, 2018
6a9d607
Merge branch 'master' into mvenkov/tree-grid-batch-update
damyanpetev Dec 7, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ All notable changes for each version of this project will be documented in this
- **Breaking change** `igxIconService` is now provided in root (providedIn: 'root') and `IgxIconModule.forRoot()` method is deprecated.
- **Breaking change** `glyphName` property of the `igxIconComponent` is deprecated.
- `IgxTreeGrid`:
- Batch editing - an injectable transaction provider accumulates pending changes, which are not directly applied to the grid's data source. Those can later be inspected, manipulated and submitted at once. Changes are collected for individual cells or rows, depending on editing mode, and accumulated per data row/record.
- You can now export the tree grid both to CSV and Excel.
- The hierarchy and the records' expanded states would be reflected in the exported Excel worksheet.

Expand Down
6 changes: 2 additions & 4 deletions projects/igniteui-angular/src/lib/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,11 @@ export function cloneHierarchicalArray(array: any[], childDataKey: any): any[] {
}

for (const item of array) {
const clonedItem = cloneValue(item);
if (Array.isArray(item[childDataKey])) {
const clonedItem = cloneValue(item);
clonedItem[childDataKey] = cloneHierarchicalArray(clonedItem[childDataKey], childDataKey);
result.push(clonedItem);
} else {
result.push(item);
}
result.push(clonedItem);
}
return result;
}
Expand Down
145 changes: 143 additions & 2 deletions projects/igniteui-angular/src/lib/data-operations/data-util.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ import { FilteringStrategy } from './filtering-strategy';
import { IFilteringExpressionsTree, FilteringExpressionsTree } from './filtering-expressions-tree';
import { IFilteringState } from './filtering-state.interface';
import { FilteringLogic } from './filtering-expression.interface';
import { IgxNumberFilteringOperand,
import {
IgxNumberFilteringOperand,
IgxStringFilteringOperand,
IgxDateFilteringOperand,
IgxBooleanFilteringOperand } from './filtering-condition';
IgxBooleanFilteringOperand
} from './filtering-condition';
import { IPagingState, PagingError } from './paging-state.interface';
import { SampleTestData } from '../test-utils/sample-test-data.spec';
import { Transaction, TransactionType, HierarchicalTransaction } from '../services';

/* Test sorting */
function testSort() {
Expand Down Expand Up @@ -266,6 +270,7 @@ function testGroupBy() {
});
}
/* //Test sorting */

/* Test filtering */
class CustomFilteringStrategy extends FilteringStrategy {
public filter<T>(data: T[], expressionsTree: IFilteringExpressionsTree): T[] {
Expand Down Expand Up @@ -387,6 +392,7 @@ function testFilter() {
});
}
/* //Test filtering */

/* Test paging */
function testPage() {
const dataGenerator: DataGenerator = new DataGenerator();
Expand Down Expand Up @@ -426,9 +432,144 @@ function testPage() {
});
}
/* //Test paging */

/* Test merging */
function testMerging() {
describe('Test merging', () => {
it('Should merge add transactions correctly', () => {
const data = SampleTestData.personIDNameData();
const addRow4 = { ID: 4, Name: 'Peter' };
const addRow5 = { ID: 5, Name: 'Mimi' };
const addRow6 = { ID: 6, Name: 'Pedro' };
const transactions: Transaction[] = [
{ id: addRow4.ID, newValue: addRow4, type: TransactionType.ADD },
{ id: addRow5.ID, newValue: addRow5, type: TransactionType.ADD },
{ id: addRow6.ID, newValue: addRow6, type: TransactionType.ADD },
];

DataUtil.mergeTransactions(data, transactions, 'ID');
expect(data.length).toBe(6);
expect(data[3]).toBe(addRow4);
expect(data[4]).toBe(addRow5);
expect(data[5]).toBe(addRow6);
});

it('Should merge update transactions correctly', () => {
const data = SampleTestData.personIDNameData();
const transactions: Transaction[] = [
{ id: 1, newValue: { Name: 'Peter' }, type: TransactionType.UPDATE },
{ id: 3, newValue: { Name: 'Mimi' }, type: TransactionType.UPDATE },
];

DataUtil.mergeTransactions(data, transactions, 'ID');
expect(data.length).toBe(3);
expect(data[0].Name).toBe('Peter');
expect(data[2].Name).toBe('Mimi');
});

it('Should merge delete transactions correctly', () => {
const data = SampleTestData.personIDNameData();
const secondRow = data[1];
const transactions: Transaction[] = [
{ id: 1, newValue: null, type: TransactionType.DELETE },
{ id: 3, newValue: null, type: TransactionType.DELETE },
];

DataUtil.mergeTransactions(data, transactions, 'ID', true);
expect(data.length).toBe(1);
expect(data[0]).toEqual(secondRow);
});

it('Should merge add hierarchical transactions correctly', () => {
const data = SampleTestData.employeeSmallTreeData();
const addRootRow = { ID: 1000, Name: 'Pit Peter', HireDate: new Date(2008, 3, 20), Age: 55 };
const addChildRow1 = { ID: 1001, Name: 'Marry May', HireDate: new Date(2018, 4, 1), Age: 102 };
const addChildRow2 = { ID: 1002, Name: 'April Alison', HireDate: new Date(2021, 5, 10), Age: 4 };
const transactions: HierarchicalTransaction[] = [
{ id: addRootRow.ID, newValue: addRootRow, type: TransactionType.ADD, path: [] },
{ id: addChildRow1.ID, newValue: addChildRow1, type: TransactionType.ADD, path: [data[0].ID, data[0].Employees[1].ID] },
{ id: addChildRow2.ID, newValue: addChildRow2, type: TransactionType.ADD, path: [addRootRow.ID] },
];

DataUtil.mergeHierarchicalTransactions(data, transactions, 'Employees', 'ID', false);
expect(data.length).toBe(4);

expect(data[3].Age).toBe(addRootRow.Age);
expect(data[3].Employees.length).toBe(1);
expect(data[3].HireDate).toBe(addRootRow.HireDate);
expect(data[3].ID).toBe(addRootRow.ID);
expect(data[3].Name).toBe(addRootRow.Name);

expect((data[0].Employees[1] as any).Employees.length).toBe(1);
expect((data[0].Employees[1] as any).Employees[0]).toBe(addChildRow1);

expect(data[3].Employees[0]).toBe(addChildRow2);
});

it('Should merge update hierarchical transactions correctly', () => {
const data = SampleTestData.employeeSmallTreeData();
const updateRootRow = { Name: 'May Peter', Age: 13 };
const updateChildRow1 = { HireDate: new Date(2100, 1, 12), Age: 1300 };
const updateChildRow2 = { HireDate: new Date(2100, 1, 12), Name: 'Santa Claus' };

const transactions: HierarchicalTransaction[] = [
{
id: data[1].ID,
newValue: updateRootRow,
type: TransactionType.UPDATE,
path: []
},
{
id: data[2].Employees[0].ID,
newValue: updateChildRow1,
type: TransactionType.UPDATE,
path: [data[2].ID]
},
{
id: (data[0].Employees[2] as any).Employees[0].ID,
newValue: updateChildRow2,
type: TransactionType.UPDATE,
path: [data[0].ID, data[0].Employees[2].ID]
},
];

DataUtil.mergeHierarchicalTransactions(data, transactions, 'Employees', 'ID', false);
expect(data[1].Name).toBe(updateRootRow.Name);
expect(data[1].Age).toBe(updateRootRow.Age);

expect(data[2].Employees[0].HireDate.getTime()).toBe(updateChildRow1.HireDate.getTime());
expect(data[2].Employees[0].Age).toBe(updateChildRow1.Age);

expect((data[0].Employees[2] as any).Employees[0].Name).toBe(updateChildRow2.Name);
expect((data[0].Employees[2] as any).Employees[0].HireDate.getTime()).toBe(updateChildRow2.HireDate.getTime());
});

it('Should merge delete hierarchical transactions correctly', () => {
const data = SampleTestData.employeeSmallTreeData();
const transactions: HierarchicalTransaction[] = [
// root row with no children
{ id: data[1].ID, newValue: null, type: TransactionType.DELETE, path: [] },
// root row with children
{ id: data[2].ID, newValue: null, type: TransactionType.DELETE, path: [] },
// child row with no children
{ id: data[0].Employees[0].ID, newValue: null, type: TransactionType.DELETE, path: [data[0].ID] },
// child row with children
{ id: data[0].Employees[2].ID, newValue: null, type: TransactionType.DELETE, path: [data[0].ID] }
];

DataUtil.mergeHierarchicalTransactions(data, transactions, 'Employees', 'ID', true);

expect(data.length).toBe(1);
expect(data[0].Employees.length).toBe(1);
});
});
}
/* //Test merging */

describe('DataUtil', () => {
testSort();
testGroupBy();
testFilter();
testPage();
testMerging();
});
113 changes: 77 additions & 36 deletions projects/igniteui-angular/src/lib/data-operations/data-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ export enum DataType {
* @hidden
*/
export class DataUtil {
public static sort<T>(data: T[], expressions: ISortingExpression [], sorting: IgxSorting = new IgxSorting()): T[] {
public static sort<T>(data: T[], expressions: ISortingExpression[], sorting: IgxSorting = new IgxSorting()): T[] {
return sorting.sort(data, expressions);
}

public static treeGridSort(hierarchicalData: ITreeGridRecord[],
expressions: ISortingExpression [],
parent?: ITreeGridRecord): ITreeGridRecord[] {
expressions: ISortingExpression[],
parent?: ITreeGridRecord): ITreeGridRecord[] {
let res: ITreeGridRecord[] = [];
hierarchicalData.forEach((hr: ITreeGridRecord) => {
const rec: ITreeGridRecord = DataUtil.cloneTreeGridRecord(hr);
Expand All @@ -58,8 +58,7 @@ export class DataUtil {
children: hierarchicalRecord.children,
isFilteredOutParent: hierarchicalRecord.isFilteredOutParent,
level: hierarchicalRecord.level,
expanded: hierarchicalRecord.expanded,
path: [...hierarchicalRecord.path]
expanded: hierarchicalRecord.expanded
};
return rec;
}
Expand Down Expand Up @@ -189,60 +188,102 @@ export class DataUtil {
* @param data Collection to merge
* @param transactions Transactions to merge into data
* @param primaryKey Primary key of the collection, if any
* @param deleteRows Should delete rows with DELETE transaction type from data
* @returns Provided data collections updated with all provided transactions
*/
public static mergeTransactions<T>(data: T[], transactions: Transaction[], primaryKey?: any): T[] {
public static mergeTransactions<T>(data: T[], transactions: Transaction[], primaryKey?: any, deleteRows: boolean = false): T[] {
data.forEach((item: any, index: number) => {
const rowId = primaryKey ? item[primaryKey] : item;
const transaction = transactions.find(t => t.id === rowId);
if (Array.isArray(item.children)) {
this.mergeTransactions(item.children, transactions, primaryKey);
}
if (transaction && transaction.type === TransactionType.UPDATE) {
data[index] = transaction.newValue;
}
});

if (deleteRows) {
damyanpetev marked this conversation as resolved.
Show resolved Hide resolved
transactions
.filter(t => t.type === TransactionType.DELETE)
.forEach(t => {
const index = primaryKey ? data.findIndex(d => d[primaryKey] === t.id) : data.findIndex(d => d === t.id);
if (0 <= index && index < data.length) {
data.splice(index, 1);
}
});
}

data.push(...transactions
.filter(t => t.type === TransactionType.ADD)
.map(t => t.newValue));

return data;
}

// TODO: optimize addition of added rows. Should not filter transaction in each recursion!!!
/** @experimental @hidden */
/**
* Merges all changes from provided transactions into provided hierarchical data collection
* @param data Collection to merge
* @param transactions Transactions to merge into data
* @param childDataKey Data key of child collections
* @param primaryKey Primary key of the collection, if any
* @param deleteRows Should delete rows with DELETE transaction type from data
* @returns Provided data collections updated with all provided transactions
*/
public static mergeHierarchicalTransactions(
data: any[],
transactions: HierarchicalTransaction[],
childDataKey: any,
primaryKey?: any,
parentKey?: any): any[] {

for (let index = 0; index < data.length; index++) {
const dataItem = data[index];
const rowId = primaryKey ? dataItem[primaryKey] : dataItem;
const updateTransaction = transactions.filter(t => t.type === TransactionType.UPDATE).find(t => t.id === rowId);
const addedTransactions = transactions.filter(t => t.type === TransactionType.ADD).filter(t => t.parentId === rowId);
if (updateTransaction || addedTransactions.length > 0) {
data[index] = mergeObjects(cloneValue(dataItem), updateTransaction && updateTransaction.newValue);
}
if (addedTransactions.length > 0) {
if (!data[index][childDataKey]) {
data[index][childDataKey] = [];
}
for (const addedTransaction of addedTransactions) {
data[index][childDataKey].push(addedTransaction.newValue);
deleteRows: boolean = false): any[] {

for (let i = 0; i < transactions.length; i++) {
const transaction = transactions[i];

if (transaction.path) {
const parent = this.findParentFromPath(data, primaryKey, childDataKey, transaction.path);
let collection: any[] = parent ? parent[childDataKey] : data;
switch (transaction.type) {
case TransactionType.ADD:
// if there is no parent this is ADD row at root level
if (parent && !parent[childDataKey]) {
parent[childDataKey] = collection = [];
}
collection.push(transaction.newValue);
break;
case TransactionType.UPDATE:
const updateIndex = collection.findIndex(x => x[primaryKey] === transaction.id);
if (updateIndex !== -1) {
collection[updateIndex] = mergeObjects(cloneValue(collection[updateIndex]), transaction.newValue);
}
break;
case TransactionType.DELETE:
if (deleteRows) {
const deleteIndex = collection.findIndex(r => r[primaryKey] === transaction.id);
if (deleteIndex !== -1) {
collection.splice(deleteIndex, 1);
}
}
break;
}
}
if (data[index][childDataKey]) {
data[index][childDataKey] = this.mergeHierarchicalTransactions(
data[index][childDataKey],
transactions,
childDataKey,
primaryKey,
rowId
);
} else {
// if there is no path this is ADD row in root. Push the newValue to data
data.push(transaction.newValue);
}
}
return data;
}

private static findParentFromPath(data: any[], primaryKey: any, childDataKey: any, path: any[]): any {
let collection: any[] = data;
let result: any;

for (const id of path) {
result = collection && collection.find(x => x[primaryKey] === id);
if (!result) {
break;
}

collection = result[childDataKey];
}

return result;
}
}
Loading