diff --git a/live-editing/configs/HierarchicalGridConfigGenerator.ts b/live-editing/configs/HierarchicalGridConfigGenerator.ts index 4bcaa1615a..7780d0d0cc 100644 --- a/live-editing/configs/HierarchicalGridConfigGenerator.ts +++ b/live-editing/configs/HierarchicalGridConfigGenerator.ts @@ -654,6 +654,15 @@ export class HierarchicalGridConfigGenerator implements IConfigGenerator { ] })); + configs.push(new Config({ + component: 'HGridCellMergeCustomComponent', + appConfig: BaseAppConfig, + additionalFiles: [ + '/src/app/directives/prevent-scroll.directive.ts', + '/src/app/data/hierarchical-data.ts' + ] + })); + configs.push(new Config({ component: 'HierarchicalGridBothSidePinningSampleComponent', appConfig: BaseAppConfig, diff --git a/live-editing/configs/TreeGridConfigGenerator.ts b/live-editing/configs/TreeGridConfigGenerator.ts index a6be295123..e1e847104a 100644 --- a/live-editing/configs/TreeGridConfigGenerator.ts +++ b/live-editing/configs/TreeGridConfigGenerator.ts @@ -800,6 +800,15 @@ export class TreeGridConfigGenerator implements IConfigGenerator { ] })); + configs.push(new Config({ + component: 'TreeGridCellMergeCustomComponent', + appConfig: BaseAppConfig, + additionalFiles: [ + '/src/app/directives/prevent-scroll.directive.ts', + '/src/app/tree-grid/data/employees-flat-detailed.ts' + ] + })); + configs.push(new Config({ component: 'TreeGridBothSidesPinningSampleComponent', additionalFiles: [ diff --git a/src/app/hierarchical-grid/hierarchical-grid-cell-merge-custom/hierarchical-grid-cell-merge-custom.component.html b/src/app/hierarchical-grid/hierarchical-grid-cell-merge-custom/hierarchical-grid-cell-merge-custom.component.html new file mode 100644 index 0000000000..ee92401348 --- /dev/null +++ b/src/app/hierarchical-grid/hierarchical-grid-cell-merge-custom/hierarchical-grid-cell-merge-custom.component.html @@ -0,0 +1,26 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/app/hierarchical-grid/hierarchical-grid-cell-merge-custom/hierarchical-grid-cell-merge-custom.component.scss b/src/app/hierarchical-grid/hierarchical-grid-cell-merge-custom/hierarchical-grid-cell-merge-custom.component.scss new file mode 100644 index 0000000000..b6f79f464f --- /dev/null +++ b/src/app/hierarchical-grid/hierarchical-grid-cell-merge-custom/hierarchical-grid-cell-merge-custom.component.scss @@ -0,0 +1,3 @@ +.grid__wrapper { + margin: 16px; +} diff --git a/src/app/hierarchical-grid/hierarchical-grid-cell-merge-custom/hierarchical-grid-cell-merge-custom.component.ts b/src/app/hierarchical-grid/hierarchical-grid-cell-merge-custom/hierarchical-grid-cell-merge-custom.component.ts new file mode 100644 index 0000000000..7050e7be58 --- /dev/null +++ b/src/app/hierarchical-grid/hierarchical-grid-cell-merge-custom/hierarchical-grid-cell-merge-custom.component.ts @@ -0,0 +1,45 @@ +import { Component } from '@angular/core'; +import { IgxHierarchicalGridComponent, IgxColumnComponent, IgxRowIslandComponent, SortingDirection, GridCellMergeMode, IgxGridToolbarComponent, IgxSelectComponent, IgxSelectItemComponent, IgxLabelDirective, DefaultMergeStrategy } from 'igniteui-angular'; +import { HIERARCHICAL_DATA } from '../../data/hierarchical-data'; +import { IgxPreventDocumentScrollDirective } from '../../directives/prevent-scroll.directive'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'app-hierarchical-grid-cell-merge-custom', + styleUrls: ['./hierarchical-grid-cell-merge-custom.component.scss'], + templateUrl: 'hierarchical-grid-cell-merge-custom.component.html', + imports: [ + IgxHierarchicalGridComponent, + IgxPreventDocumentScrollDirective, + IgxColumnComponent, + IgxRowIslandComponent, + IgxGridToolbarComponent, + IgxSelectComponent, + IgxSelectItemComponent, + IgxLabelDirective, + FormsModule + ] +}) + +export class HGridCellMergeCustomComponent { + + public localData = HIERARCHICAL_DATA; + public cellMergeMode: GridCellMergeMode = 'always'; + public perCountryMergeStrategy = new PerCountryMergeStrategy(); + public sortExpr = [ + { + dir: SortingDirection.Asc, fieldName: 'ContactTitle' + } + ]; +} + +export class PerCountryMergeStrategy extends DefaultMergeStrategy { + /* Merge only cells within their respective countries */ + public override comparer(prevRecord: any, record: any, field: string): boolean { + const a = prevRecord[field]; + const b = record[field]; + const projA = prevRecord['Country']; + const projB = record['Country']; + return a === b && projA === projB; + } +} diff --git a/src/app/hierarchical-grid/hierarchical-grid-routes-data.ts b/src/app/hierarchical-grid/hierarchical-grid-routes-data.ts index 4c0e458c6c..7108106df7 100644 --- a/src/app/hierarchical-grid/hierarchical-grid-routes-data.ts +++ b/src/app/hierarchical-grid/hierarchical-grid-routes-data.ts @@ -2,6 +2,7 @@ export const hierarchicalGridRoutesData = { 'hierarchical-grid-cell-merge': { displayName: 'Hierarchical Grid Cell Merging', parentName: 'Hierarchical Grid' }, + 'hierarchical-grid-cell-merge-custom': { displayName: 'Hierarchical Grid Cell Merging Custom', parentName: 'Hierarchical Grid' }, 'hierarchical-grid-editing': { displayName: 'Hierarchical Grid Editing', parentName: 'Hierarchical Grid' }, 'hierarchical-grid-editing-events': { displayName: 'Hierarchical Grid Editing Events', parentName: 'Hierarchical Grid'}, 'hierarchical-grid-editing-style': { displayName: 'Hierarchical Grid Editing Style', parentName: 'Hierarchical Grid'}, diff --git a/src/app/hierarchical-grid/hierarchical-grid.routes.ts b/src/app/hierarchical-grid/hierarchical-grid.routes.ts index 27a130a6d0..8df4ab23fd 100644 --- a/src/app/hierarchical-grid/hierarchical-grid.routes.ts +++ b/src/app/hierarchical-grid/hierarchical-grid.routes.ts @@ -103,6 +103,7 @@ import { HierarchicalGridValidatorServiceExtendedComponent } from './hierarchica import { HGridSummaryExportComponent } from './hgrid-summary-export/hgrid-summary-export.component'; import { HierarchicalGridBothSidePinningSampleComponent } from './hierarchical-grid-sample-both-sides-pinning/hierarchical-grid-both-sides-pinning.component'; import { HGridCellMergeComponent } from './hierarchical-grid-cell-merge/hierarchical-grid-cell-merge.component'; +import { HGridCellMergeCustomComponent } from './hierarchical-grid-cell-merge-custom/hierarchical-grid-cell-merge-custom.component'; export const HierarchicalGridRoutes: Routes = [ { @@ -593,5 +594,10 @@ export const HierarchicalGridRoutes: Routes = [ component: HGridCellMergeComponent, data: hierarchicalGridRoutesData['hierarchical-grid-cell-merge'], path: 'hierarchical-grid-cell-merge' + }, + { + component: HGridCellMergeCustomComponent, + data: hierarchicalGridRoutesData['hierarchical-grid-cell-merge-custom'], + path: 'hierarchical-grid-cell-merge-custom' } ]; diff --git a/src/app/tree-grid/data/employees-flat-detailed2.ts b/src/app/tree-grid/data/employees-flat-detailed2.ts new file mode 100644 index 0000000000..1a7bd8396e --- /dev/null +++ b/src/app/tree-grid/data/employees-flat-detailed2.ts @@ -0,0 +1,269 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +export const generateEmployeeDetailedFlatData2 = () => ([ + { + Address: 'Obere Str. 57', + Age: 55, + City: 'Berlin', + Country: 'Germany', + Fax: '030-0076545', + HireDate: new Date(2008, 3, 20), + ID: 1, + Name: 'Johnathan Winchester', + ParentID: -1, + Phone: '030-0074321', + PostalCode: '12209', + Title: 'Development Manager' + }, + { + Address: 'Forsterstr. 57', + Age: 29, + City: 'Berlin', + Country: 'Germany', + Fax: '0621-08924', + HireDate: new Date(2009, 6, 19), + ID: 2, + Name: 'Thomas Anderson', + ParentID: 1, + Phone: '0621-08460', + PostalCode: '68306', + Title: 'Senior Software Developer' + }, + { + Address: 'Berguvsvägen 8', + Age: 43, + City: 'Berlin', + Country: 'Germany', + Fax: '0921-12 34 67', + HireDate: new Date(2011, 6, 3), + ID: 3, + Name: 'Michael Burke', + ParentID: 1, + Phone: '0921-12 34 65', + PostalCode: 'S-958 22', + Title: 'Senior Software Developer' + }, + { + Address: 'Hauptstr. 29', + Age: 50, + City: 'Berlin', + Country: 'Germany', + Fax: '(5) 555-6691', + HireDate: new Date(2007, 11, 18), + ID: 19, + Name: 'Klaus Schmidt', + ParentID: 1, + Phone: '0452-076545', + PostalCode: '3012', + Title: 'Senior Software Developer' + }, + { + Address: 'Walserweg 21', + Age: 39, + City: 'Berlin', + Country: 'Germany', + Fax: '0241-059428', + HireDate: new Date(2010, 3, 22), + ID: 9, + Name: 'Francisco Chang', + ParentID: 1, + Phone: '0241-039123', + PostalCode: '52066', + Title: 'Senior Software Developer' + }, + { + Address: 'Avda. de la Constitución 2222', + Age: 42, + City: 'México D.F.', + Country: 'Mexico', + Fax: '(5) 555-3745', + HireDate: new Date(2014, 1, 22), + ID: 4, + Name: 'Ana Sanders', + ParentID: -1, + Phone: '(5) 555-4729', + PostalCode: '05021', + Title: 'CEO' + }, + { + Address: 'Mataderos 2312', + Age: 49, + City: 'México D.F.', + Country: 'Mexico', + Fax: '(5) 555-3995', + HireDate: new Date(2014, 1, 22), + ID: 18, + Name: 'Victoria Lincoln', + ParentID: -1, + Phone: '(5) 555-3932', + PostalCode: '05023', + Title: 'Accounting Manager' + }, + { + Address: 'Sierras de Granada 9993', + Age: 44, + City: 'México D.F.', + Country: 'Mexico', + Fax: '(5) 555-7293', + HireDate: new Date(2014, 4, 4), + ID: 17, + Name: 'Antonio Moreno', + ParentID: 18, + Phone: '(5) 555-3392', + PostalCode: '05022', + Title: 'Senior Accountant' + }, + { + Address: 'Cerrito 333', + Age: 39, + City: 'Buenos Aires', + Country: 'Argentina', + Fax: '(1) 135-4892', + HireDate: new Date(2010, 3, 22), + ID: 13, + Name: 'Trevor Ashworth', + ParentID: 5, + Phone: '(1) 135-5555', + PostalCode: '1010', + Title: 'Director' + }, + { + Address: '23 Tsawassen Blvd.', + Age: 44, + City: 'Toronto', + Country: 'Canada', + Fax: '(604) 555-3745', + HireDate: new Date(2014, 4, 4), + ID: 14, + Name: 'Laurence Johnson', + ParentID: 4, + Phone: '(604) 555-4729', + PostalCode: 'T2F 8M4', + Title: 'Director' + }, + { + Address: 'Fauntleroy Circus', + Age: 25, + City: 'London', + Country: 'UK', + Fax: '(5) 555-3798', + HireDate: new Date(2017, 11, 9), + ID: 5, + Name: 'Elizabeth Richards', + ParentID: 4, + Phone: '(171) 555-1212', + PostalCode: 'EC2 5NT', + Title: 'Vice President' + }, + { + Address: '120 Hanover Sq.', + Age: 61, + City: 'London', + Country: 'UK', + Fax: '(171) 555-6750', + HireDate: new Date(2010, 1, 1), + ID: 10, + Name: 'Yang Wang', + ParentID: -1, + Phone: '(171) 555-7788', + PostalCode: 'WA1 1DP', + Title: 'Localization Manager' + }, + { + Address: 'Berkeley Gardens 12', + Age: 25, + City: 'London', + Country: 'UK', + Fax: '(171) 555-9199', + HireDate: new Date(2017, 11, 9), + ID: 15, + Name: 'Patricia Simpson', + ParentID: 10, + Phone: '(171) 555-2282', + PostalCode: 'WX1 6LT', + Title: 'Localization Intern' + }, + { + Address: '35 King George', + Age: 25, + City: 'London', + Country: 'UK', + Fax: '(171) 555-3373', + HireDate: new Date(2018, 3, 18), + ID: 16, + Name: 'Peter Lewis', + ParentID: 10, + Phone: '(171) 555-0297', + PostalCode: 'WX3 6FW', + Title: 'Localization Intern' + }, + { + Address: 'Walserweg 21', + Age: 39, + City: 'London', + Country: 'UK', + Fax: '0241-059428', + HireDate: new Date(2010, 3, 22), + ID: 20, + Name: 'Linda Brown', + ParentID: 10, + Phone: '0241-039123', + PostalCode: '52066', + Title: 'Localization Intern' + }, + { + Address: 'Av. dos Lusíadas, 23', + Age: 27, + City: 'Bern', + Country: 'Switzerland', + Fax: '', + HireDate: new Date(2016, 2, 19), + ID: 8, + Name: 'Casey Harper', + ParentID: 10, + Phone: '(11) 555-7647', + PostalCode: '05432-043', + Title: 'Senior Localization' + }, + { + Address: '24, place Kléber', + Age: 31, + City: 'Strasbourg', + Country: 'France', + Fax: '88.60.15.32', + HireDate: new Date(2014, 8, 18), + ID: 11, + Name: 'Monica Reyes', + ParentID: 1, + Phone: '88.60.15.31', + PostalCode: '67000', + Title: 'Software Development Team Lead' + }, + { + Address: 'C/ Araquil, 67', + Age: 35, + City: 'Madrid', + Country: 'Spain', + Fax: '(91) 555 91 99', + HireDate: new Date(2015, 9, 17), + ID: 6, + Name: 'Roland Mendel', + ParentID: 11, + Phone: '(91) 555 22 82', + PostalCode: '28023', + Title: 'Senior Software Developer' + }, + { + Address: '12, rue des Bouchers', + Age: 44, + City: 'Marseille', + Country: 'France', + Fax: '91.24.45.41', + HireDate: new Date(2009, 10, 11), + ID: 12, + Name: 'Sven Cooper', + ParentID: 11, + Phone: '91.24.45.40', + PostalCode: '13008', + Title: 'Senior Software Developer' + } +]); \ No newline at end of file diff --git a/src/app/tree-grid/tree-grid-cell-merge-custom-sample/tree-grid-cell-merge-custom-sample.component.html b/src/app/tree-grid/tree-grid-cell-merge-custom-sample/tree-grid-cell-merge-custom-sample.component.html new file mode 100644 index 0000000000..d74ec34ca1 --- /dev/null +++ b/src/app/tree-grid/tree-grid-cell-merge-custom-sample/tree-grid-cell-merge-custom-sample.component.html @@ -0,0 +1,17 @@ +
+ + + + + + + + + + + + + +
diff --git a/src/app/tree-grid/tree-grid-cell-merge-custom-sample/tree-grid-cell-merge-custom-sample.component.scss b/src/app/tree-grid/tree-grid-cell-merge-custom-sample/tree-grid-cell-merge-custom-sample.component.scss new file mode 100644 index 0000000000..58232c0b31 --- /dev/null +++ b/src/app/tree-grid/tree-grid-cell-merge-custom-sample/tree-grid-cell-merge-custom-sample.component.scss @@ -0,0 +1,11 @@ +.grid__wrapper { + + position: relative; + width: 100%; + height: 100%; + top: 0; + left: 0; + padding: 15px; + display: flex; + flex-direction: column; +} diff --git a/src/app/tree-grid/tree-grid-cell-merge-custom-sample/tree-grid-cell-merge-custom-sample.component.ts b/src/app/tree-grid/tree-grid-cell-merge-custom-sample/tree-grid-cell-merge-custom-sample.component.ts new file mode 100644 index 0000000000..8e9aee0c8b --- /dev/null +++ b/src/app/tree-grid/tree-grid-cell-merge-custom-sample/tree-grid-cell-merge-custom-sample.component.ts @@ -0,0 +1,66 @@ +import { Component, ViewChild } from '@angular/core'; +import { IgxTreeGridComponent, IgxColumnComponent, GridCellMergeMode, IgxGridToolbarComponent, IgxSelectComponent, IgxSelectItemComponent, IgxLabelDirective, SortingDirection, DefaultMergeStrategy } from 'igniteui-angular'; +import { IgxPreventDocumentScrollDirective } from '../../directives/prevent-scroll.directive'; +import { FormsModule } from '@angular/forms'; +import { generateEmployeeDetailedFlatData2 } from '../data/employees-flat-detailed2'; + +@Component({ + selector: 'app-tree-grid-cell-merge-custom-sample', + styleUrls: ['./tree-grid-cell-merge-custom-sample.component.scss'], + templateUrl: './tree-grid-cell-merge-custom-sample.component.html', + imports: [ + IgxTreeGridComponent, + IgxPreventDocumentScrollDirective, + IgxColumnComponent, + IgxSelectComponent, + IgxSelectItemComponent, + IgxLabelDirective, + IgxGridToolbarComponent, + FormsModule + ] +}) + +export class TreeGridCellMergeCustomComponent { + @ViewChild('treeGrid', { static: true }) public treeGrid: IgxTreeGridComponent; + public childDataKey = 'Categories'; + public data = generateEmployeeDetailedFlatData2(); + public cellMergeMode: GridCellMergeMode = 'always'; + public sortExpr = [ + { + dir: SortingDirection.Asc, fieldName: 'Country' + } + ]; + //public mergeTypes = [{ name: 'Always', value: GridCellMergeMode.always }, { name: 'On sort', value: GridCellMergeMode.onSort }]; + + //public mergeStrategies = [{ name: 'Default Strategy', value: new DefaultTreeGridMergeStrategy() }, { name: 'By Level Strategy', value: new ByLevelTreeGridMergeStrategy() }]; + public mergeStrategy = new CustomTreeGridMergeStrategy(); + /* public strategySelection(e) { + this.mergeStrategy = e.newSelection.value; + } */ +} + +export class CustomTreeGridMergeStrategy extends DefaultMergeStrategy { + /* Merge only cells within their respective countries and levels */ + public override comparer(prevRecord: any, record: any, field: string, isDate = false, isTime = false): boolean { + const a = this.getFieldValue(prevRecord.data, field, isDate, isTime); + const b = this.getFieldValue(record.data, field, isDate, isTime); + + const levelA = prevRecord.level; + const levelB = record.level; + + const countryA = prevRecord.data['Country']; + const countryB = record.data['Country']; + + const an = (a === null || a === undefined); + const bn = (b === null || b === undefined); + + if (an) { + return bn; // both null/undefined → merge, else → no merge + } else if (bn) { + return false; + } + + // Merge only if values match, level matches, and country matches + return a === b && levelA === levelB && countryA === countryB; + } +} diff --git a/src/app/tree-grid/tree-grid-routes-data.ts b/src/app/tree-grid/tree-grid-routes-data.ts index 2f61fc0553..3efb24ebf7 100644 --- a/src/app/tree-grid/tree-grid-routes-data.ts +++ b/src/app/tree-grid/tree-grid-routes-data.ts @@ -2,6 +2,7 @@ export const treeGridRoutesData = { 'treegrid-cell-merge': { displayName: 'TreeGrid Cell Merge', parentName: 'TreeGrid' }, + 'treegrid-cell-merge-custom': { displayName: 'TreeGrid Cell Merge Custom', parentName: 'TreeGrid' }, 'tree-grid-row-drag': { displayName: 'Tree Grid Row Drag', parentName: 'TreeGrid' }, 'tree-grid-multi-row-drag': { displayName: 'Tree Grid Multi Row Drag', parentName: 'TreeGrid' }, 'tree-grid-row-drag-base': { displayName: 'Tree Grid Row Drag - Base', parentName: 'TreeGrid' }, diff --git a/src/app/tree-grid/tree-grid.routes.ts b/src/app/tree-grid/tree-grid.routes.ts index 7f1f686f77..355664fe87 100644 --- a/src/app/tree-grid/tree-grid.routes.ts +++ b/src/app/tree-grid/tree-grid.routes.ts @@ -102,6 +102,7 @@ import { TreeGridValidationStyleComponent } from './tree-grid-validation-style/t import { TreeGridSummaryExportComponent } from './tree-grid-summary-export/tree-grid-summary-export.component'; import { TreeGridBothSidesPinningSampleComponent } from './tree-grid-sample-both-pinning/tree-grid-both-sides-pinning.component'; import { TreeGridCellMergeComponent } from './tree-grid-cell-merge-sample/tree-grid-cell-merge-sample.component'; +import { TreeGridCellMergeCustomComponent } from './tree-grid-cell-merge-custom-sample/tree-grid-cell-merge-custom-sample.component'; export const TreeGridRoutes: Routes = [ { @@ -608,5 +609,10 @@ export const TreeGridRoutes: Routes = [ component: TreeGridCellMergeComponent, data: treeGridRoutesData['treegrid-cell-merge'], path: 'treegrid-cell-merge' + }, + { + component: TreeGridCellMergeCustomComponent, + data: treeGridRoutesData['treegrid-cell-merge-custom'], + path: 'treegrid-cell-merge-custom' } ];