Skip to content

Commit

Permalink
feat(selection): add flag to disable syncGridSelection w/BackendServi…
Browse files Browse the repository at this point in the history
…ce (#390)
  • Loading branch information
ghiscoding committed Jan 31, 2020
1 parent 141d01a commit f29c6f0
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
expect(sortSpy).toHaveBeenCalled();
});

it('should call the DataView syncGridSelection method with 2nd argument as True when the "dataView" grid option is a boolean and is set to True', () => {
it('should call the DataView "syncGridSelection" method with 2nd argument as True when the "dataView.syncGridSelection" grid option is enabled', () => {
jest.spyOn(mockGrid, 'getSelectionModel').mockReturnValue(true);
const syncSpy = jest.spyOn(mockDataView, 'syncGridSelection');

Expand All @@ -503,7 +503,17 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
expect(syncSpy).toHaveBeenCalledWith(component.grid, true);
});

it('should call the DataView syncGridSelection method with 3 arguments when the "dataView" grid option is provided as an object', () => {
it('should call the DataView "syncGridSelection" method with 2nd argument as False when the "dataView.syncGridSelection" grid option is disabled', () => {
jest.spyOn(mockGrid, 'getSelectionModel').mockReturnValue(true);
const syncSpy = jest.spyOn(mockDataView, 'syncGridSelection');

component.gridOptions = { dataView: { syncGridSelection: false }, enableRowSelection: true } as GridOption;
component.ngAfterViewInit();

expect(syncSpy).toHaveBeenCalledWith(component.grid, false);
});

it('should call the DataView "syncGridSelection" method with 3 arguments when the "dataView" grid option is provided as an object', () => {
jest.spyOn(mockGrid, 'getSelectionModel').mockReturnValue(true);
const syncSpy = jest.spyOn(mockDataView, 'syncGridSelection');

Expand All @@ -516,6 +526,57 @@ describe('Angular-Slickgrid Custom Component instantiated via Constructor', () =
expect(syncSpy).toHaveBeenCalledWith(component.grid, true, false);
});

it('should call the DataView "syncGridSelection" method when using BackendServiceApi and "syncGridSelectionWithBackendService" when the "dataView.syncGridSelection" grid option is enabled as well', () => {
jest.spyOn(mockGrid, 'getSelectionModel').mockReturnValue(true);
const syncSpy = jest.spyOn(mockDataView, 'syncGridSelection');

component.gridOptions = {
backendServiceApi: {
service: mockGraphqlService,
process: jest.fn(),
},
dataView: { syncGridSelection: true, syncGridSelectionWithBackendService: true },
enableRowSelection: true
} as GridOption;
component.ngAfterViewInit();

expect(syncSpy).toHaveBeenCalledWith(component.grid, true);
});

it('should call the DataView "syncGridSelection" method with false as 2nd argument when using BackendServiceApi and "syncGridSelectionWithBackendService" BUT the "dataView.syncGridSelection" grid option is disabled', () => {
jest.spyOn(mockGrid, 'getSelectionModel').mockReturnValue(true);
const syncSpy = jest.spyOn(mockDataView, 'syncGridSelection');

component.gridOptions = {
backendServiceApi: {
service: mockGraphqlService,
process: jest.fn(),
},
dataView: { syncGridSelection: false, syncGridSelectionWithBackendService: true },
enableRowSelection: true
} as GridOption;
component.ngAfterViewInit();

expect(syncSpy).toHaveBeenCalledWith(component.grid, false);
});

it('should call the DataView "syncGridSelection" method with false as 2nd argument when using BackendServiceApi and "syncGridSelectionWithBackendService" disabled and the "dataView.syncGridSelection" grid option is enabled', () => {
jest.spyOn(mockGrid, 'getSelectionModel').mockReturnValue(true);
const syncSpy = jest.spyOn(mockDataView, 'syncGridSelection');

component.gridOptions = {
backendServiceApi: {
service: mockGraphqlService,
process: jest.fn(),
},
dataView: { syncGridSelection: true, syncGridSelectionWithBackendService: false },
enableRowSelection: true
} as GridOption;
component.ngAfterViewInit();

expect(syncSpy).toHaveBeenCalledWith(component.grid, false);
});

it('should bind local filter when "enableFiltering" is set', () => {
const bindLocalSpy = jest.spyOn(filterServiceStub, 'bindLocalOnFilter');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -740,9 +740,21 @@ export class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnIn
// to stay selected, pass 'false' to the second arg
const selectionModel = this.grid && this.grid.getSelectionModel();
if (selectionModel && this.gridOptions && this.gridOptions.dataView && this.gridOptions.dataView.hasOwnProperty('syncGridSelection')) {
// if we are using a Backend Service, we will do an extra flag check, the reason is because it might have some unintended behaviors
// with the BackendServiceApi because technically the data in the page changes the DataView on every page change.
let preservedRowSelectionWithBackend = false;
if (this.gridOptions.backendServiceApi && this.gridOptions.dataView.hasOwnProperty('syncGridSelectionWithBackendService')) {
preservedRowSelectionWithBackend = this.gridOptions.dataView.syncGridSelectionWithBackendService;
}

const syncGridSelection = this.gridOptions.dataView.syncGridSelection;
if (typeof syncGridSelection === 'boolean') {
this.dataView.syncGridSelection(this.grid, this.gridOptions.dataView.syncGridSelection);
let preservedRowSelection = syncGridSelection;
if (!this._isLocalGrid) {
// when using BackendServiceApi, we'll be using the "syncGridSelectionWithBackendService" flag BUT "syncGridSelection" must also be set to True
preservedRowSelection = syncGridSelection && preservedRowSelectionWithBackend;
}
this.dataView.syncGridSelection(this.grid, preservedRowSelection);
} else if (typeof syncGridSelection === 'object') {
this.dataView.syncGridSelection(this.grid, syncGridSelection.preserveHidden, syncGridSelection.preserveHiddenOnSelectionChange);
}
Expand Down
3 changes: 2 additions & 1 deletion src/app/modules/angular-slickgrid/global-grid-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ export const GlobalGridOptions: Partial<GridOption> = {
}
},
dataView: {
syncGridSelection: true // when enabled, this will preserve the row selection even after filtering/sorting/grouping
syncGridSelection: true, // when enabled, this will preserve the row selection even after filtering/sorting/grouping
syncGridSelectionWithBackendService: false, // but disable it when using backend services
},
datasetIdPropertyName: 'id',
defaultFilter: Filters.input,
Expand Down
11 changes: 9 additions & 2 deletions src/app/modules/angular-slickgrid/models/gridOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,17 @@ export interface GridOption {
/** Some of the SlickGrid DataView options */
dataView?: {
/**
* If you don't want the items that are not visible (due to being filtered out or being on a different page)
* to stay selected, the set this property as 'false'. You can also set any of the preserve options instead of a boolean value.
* Defaults to true, when using row selection,
* if you don't want the items that are not visible (due to being filtered out or being on a different page) to stay selected,
* then set this property as 'false'. You can also set any of the preserve options instead of a boolean value.
*/
syncGridSelection?: boolean | { preserveHidden: boolean; preserveHiddenOnSelectionChange: boolean; };

/**
* Defaults to false, do we also want to keep the row selections kept between the pages when using BackendServiceApi?
* Note that this flag will be skipped if "syncGridSelection" is already disabled, both flags are used in conjunction
*/
syncGridSelectionWithBackendService?: boolean;
};

/** Default column width, is set to 80 when null */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ describe('GridStateService', () => {

const output = service.needToPreserveRowSelection();

expect(output).toBeFalsy();
expect(output).toBeFalse();
});

it('should return false when "dataView" property is defined in the grid options with "syncGridSelection" property', () => {
Expand All @@ -710,7 +710,7 @@ describe('GridStateService', () => {

const output = service.needToPreserveRowSelection();

expect(output).toBeFalsy();
expect(output).toBeFalse();
});

it('should return true when the "dataView" grid option is a boolean and is set to True', () => {
Expand All @@ -719,7 +719,39 @@ describe('GridStateService', () => {

const output = service.needToPreserveRowSelection();

expect(output).toBeTruthy();
expect(output).toBeTrue();
});

it('should return false when using BackendServiceApi and the "dataView" grid option is a boolean and is set to True but "syncGridSelectionWithBackendService" is disabled', () => {
const gridOptionsMock = {
dataView: { syncGridSelection: true, syncGridSelectionWithBackendService: false },
backendServiceApi: {
service: backendServiceStub,
process: jest.fn(),
},
enableRowSelection: true
} as GridOption;
jest.spyOn(gridStub, 'getOptions').mockReturnValue(gridOptionsMock);

const output = service.needToPreserveRowSelection();

expect(output).toBeFalse();
});

it('should return true when using BackendServiceApi and the "dataView" grid option is a boolean and is set to True but "syncGridSelectionWithBackendService" is enabled', () => {
const gridOptionsMock = {
dataView: { syncGridSelection: true, syncGridSelectionWithBackendService: true },
backendServiceApi: {
service: backendServiceStub,
process: jest.fn(),
},
enableRowSelection: true
} as GridOption;
jest.spyOn(gridStub, 'getOptions').mockReturnValue(gridOptionsMock);

const output = service.needToPreserveRowSelection();

expect(output).toBeTrue();
});

it('should return true when the "dataView" grid option is provided as an object', () => {
Expand All @@ -731,7 +763,7 @@ describe('GridStateService', () => {

const output = service.needToPreserveRowSelection();

expect(output).toBeTruthy();
expect(output).toBeTrue();
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,12 @@ export class GridStateService {
} else {
preservedRowSelection = syncGridSelection.preserveHidden;
}

// if the result is True but the grid is using a Backend Service, we will do an extra flag check the reason is because it might have some unintended behaviors
// with the BackendServiceApi because technically the data in the page changes the DataView on every page.
if (preservedRowSelection && this._gridOptions.backendServiceApi && this._gridOptions.dataView.hasOwnProperty('syncGridSelectionWithBackendService')) {
preservedRowSelection = this._gridOptions.dataView.syncGridSelectionWithBackendService;
}
}
return preservedRowSelection;
}
Expand Down

0 comments on commit f29c6f0

Please sign in to comment.