-
-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(service): add GridEvent Service to the lib
- Loading branch information
1 parent
ba6390a
commit 4a4bf6f
Showing
7 changed files
with
365 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
240 changes: 240 additions & 0 deletions
240
packages/common/src/services/__tests__/gridEvent.service.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
import { GridEventService } from '../gridEvent.service'; | ||
import { Column } from '../../interfaces/index'; | ||
|
||
declare const Slick: any; | ||
|
||
const dataViewStub = { | ||
refresh: jest.fn(), | ||
sort: jest.fn(), | ||
reSort: jest.fn(), | ||
}; | ||
|
||
const gridStub = { | ||
getColumnIndex: jest.fn(), | ||
getColumns: jest.fn(), | ||
getDataItem: jest.fn(), | ||
getOptions: jest.fn(), | ||
setActiveCell: jest.fn(), | ||
setColumns: jest.fn(), | ||
setSortColumns: jest.fn(), | ||
onBeforeEditCell: new Slick.Event(), | ||
onCellChange: new Slick.Event(), | ||
onClick: new Slick.Event(), | ||
}; | ||
|
||
describe('GridEventService', () => { | ||
let service: GridEventService; | ||
|
||
beforeEach(() => { | ||
service = new GridEventService(); | ||
}); | ||
|
||
afterEach(() => { | ||
service.dispose(); | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
describe('bindOnBeforeEditCell method', () => { | ||
let mockColumn; | ||
let mockRowData; | ||
|
||
beforeEach(() => { | ||
mockColumn = { id: 'firstName', field: 'firstName', onBeforeEditCell: jest.fn() } as Column; | ||
mockRowData = { firstName: 'John', lastName: 'Doe' }; | ||
}); | ||
|
||
it('should not do anything when no arguments are provided to the event', () => { | ||
const spyGetCols = jest.spyOn(gridStub, 'getColumns').mockReturnValue([mockColumn]); | ||
|
||
service.bindOnBeforeEditCell(gridStub, dataViewStub); | ||
gridStub.onBeforeEditCell.notify(undefined, new Slick.EventData(), gridStub); | ||
|
||
expect(spyGetCols).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should not do anything when "cell" property is missing', () => { | ||
const spyGetCols = jest.spyOn(gridStub, 'getColumns').mockReturnValue([mockColumn]); | ||
|
||
service.bindOnBeforeEditCell(gridStub, dataViewStub); | ||
gridStub.onBeforeEditCell.notify({ cell: undefined, row: undefined }, new Slick.EventData(), gridStub); | ||
|
||
expect(spyGetCols).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should execute the column "onBeforeEditCell" callback method', () => { | ||
const spyGetCols = jest.spyOn(gridStub, 'getColumns').mockReturnValue([mockColumn]); | ||
const spyGetData = jest.spyOn(gridStub, 'getDataItem').mockReturnValue(mockRowData); | ||
const spyOnChange = jest.spyOn(mockColumn, 'onBeforeEditCell'); | ||
|
||
service.bindOnBeforeEditCell(gridStub, dataViewStub); | ||
gridStub.onBeforeEditCell.notify({ cell: 0, row: 0 }, new Slick.EventData(), gridStub); | ||
|
||
expect(spyGetCols).toHaveBeenCalled(); | ||
expect(spyGetData).toHaveBeenCalled(); | ||
expect(spyOnChange).toHaveBeenCalledWith(expect.anything(), { | ||
row: 0, | ||
cell: 0, | ||
dataView: dataViewStub, | ||
grid: gridStub, | ||
columnDef: mockColumn, | ||
dataContext: mockRowData | ||
}); | ||
}); | ||
}); | ||
|
||
describe('bindOnCellChange method', () => { | ||
let mockColumn; | ||
let mockRowData; | ||
|
||
beforeEach(() => { | ||
mockColumn = { id: 'firstName', field: 'firstName', onCellChange: jest.fn() } as Column; | ||
mockRowData = { firstName: 'John', lastName: 'Doe' }; | ||
}); | ||
|
||
it('should not do anything when no arguments are provided to the event', () => { | ||
const spyGetCols = jest.spyOn(gridStub, 'getColumns').mockReturnValue([mockColumn]); | ||
|
||
service.bindOnCellChange(gridStub, dataViewStub); | ||
gridStub.onCellChange.notify(undefined, new Slick.EventData(), gridStub); | ||
|
||
expect(spyGetCols).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should not do anything when "cell" property is missing', () => { | ||
const spyGetCols = jest.spyOn(gridStub, 'getColumns').mockReturnValue([mockColumn]); | ||
|
||
service.bindOnCellChange(gridStub, dataViewStub); | ||
gridStub.onCellChange.notify({ cell: undefined, row: undefined }, new Slick.EventData(), gridStub); | ||
|
||
expect(spyGetCols).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should execute the column "onCellChange" callback method', () => { | ||
const spyGetCols = jest.spyOn(gridStub, 'getColumns').mockReturnValue([mockColumn]); | ||
const spyGetData = jest.spyOn(gridStub, 'getDataItem').mockReturnValue(mockRowData); | ||
const spyOnChange = jest.spyOn(mockColumn, 'onCellChange'); | ||
|
||
service.bindOnCellChange(gridStub, dataViewStub); | ||
gridStub.onCellChange.notify({ cell: 0, row: 0 }, new Slick.EventData(), gridStub); | ||
|
||
expect(spyGetCols).toHaveBeenCalled(); | ||
expect(spyGetData).toHaveBeenCalled(); | ||
expect(spyOnChange).toHaveBeenCalledWith(expect.anything(), { | ||
row: 0, | ||
cell: 0, | ||
dataView: dataViewStub, | ||
grid: gridStub, | ||
columnDef: mockColumn, | ||
dataContext: mockRowData | ||
}); | ||
}); | ||
}); | ||
|
||
describe('bindOnClick method', () => { | ||
let mockColumn; | ||
let mockRowData; | ||
|
||
beforeEach(() => { | ||
mockColumn = { id: 'firstName', field: 'firstName', onCellClick: jest.fn() } as Column; | ||
mockRowData = { firstName: 'John', lastName: 'Doe' }; | ||
}); | ||
|
||
it('should not do anything when no arguments are provided to the event', () => { | ||
const spyGetCols = jest.spyOn(gridStub, 'getColumns').mockReturnValue([mockColumn]); | ||
|
||
service.bindOnClick(gridStub, dataViewStub); | ||
gridStub.onClick.notify(undefined, new Slick.EventData(), gridStub); | ||
|
||
expect(spyGetCols).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should not do anything when "cell" property is missing', () => { | ||
const spyGetCols = jest.spyOn(gridStub, 'getColumns').mockReturnValue([mockColumn]); | ||
|
||
service.bindOnClick(gridStub, dataViewStub); | ||
gridStub.onClick.notify({ cell: undefined, row: undefined }, new Slick.EventData(), gridStub); | ||
|
||
expect(spyGetCols).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should execute the column "onCellClick" callback method', () => { | ||
gridStub.getOptions = undefined; | ||
const spyGetCols = jest.spyOn(gridStub, 'getColumns').mockReturnValue([mockColumn]); | ||
const spyGetData = jest.spyOn(gridStub, 'getDataItem').mockReturnValue(mockRowData); | ||
const spyOnChange = jest.spyOn(mockColumn, 'onCellClick'); | ||
|
||
service.bindOnClick(gridStub, dataViewStub); | ||
gridStub.onClick.notify({ cell: 0, row: 0 }, new Slick.EventData(), gridStub); | ||
|
||
expect(spyGetCols).toHaveBeenCalled(); | ||
expect(spyGetData).toHaveBeenCalled(); | ||
expect(spyOnChange).toHaveBeenCalledWith(expect.anything(), { | ||
row: 0, | ||
cell: 0, | ||
dataView: dataViewStub, | ||
grid: gridStub, | ||
columnDef: mockColumn, | ||
dataContext: mockRowData | ||
}); | ||
}); | ||
|
||
it('should execute the column "onCellClick" callback method and "setActiveCell" cell navigation is enabled but column is not editable', () => { | ||
gridStub.getOptions = jest.fn(); | ||
jest.spyOn(gridStub, 'getOptions').mockReturnValue({ enableCellNavigation: true, editable: false }); | ||
const spyActive = jest.spyOn(gridStub, 'setActiveCell'); | ||
const spyGetCols = jest.spyOn(gridStub, 'getColumns').mockReturnValue([mockColumn]); | ||
const spyGetData = jest.spyOn(gridStub, 'getDataItem').mockReturnValue(mockRowData); | ||
const spyOnChange = jest.spyOn(mockColumn, 'onCellClick'); | ||
|
||
service.bindOnClick(gridStub, dataViewStub); | ||
gridStub.onClick.notify({ cell: 0, row: 0 }, new Slick.EventData(), gridStub); | ||
|
||
expect(spyActive).toHaveBeenCalled(); | ||
expect(spyGetCols).toHaveBeenCalled(); | ||
expect(spyGetData).toHaveBeenCalled(); | ||
expect(spyOnChange).toHaveBeenCalledWith(expect.anything(), { | ||
row: 0, | ||
cell: 0, | ||
dataView: dataViewStub, | ||
grid: gridStub, | ||
columnDef: mockColumn, | ||
dataContext: mockRowData | ||
}); | ||
}); | ||
|
||
it('should execute the column "onCellClick" callback method and "setActiveCell" when cell is editable and autoCommitEdit', () => { | ||
gridStub.getOptions = jest.fn(); | ||
jest.spyOn(gridStub, 'getOptions').mockReturnValue({ enableCellNavigation: true, editable: true, autoCommitEdit: true }); | ||
const spyActive = jest.spyOn(gridStub, 'setActiveCell'); | ||
const spyGetCols = jest.spyOn(gridStub, 'getColumns').mockReturnValue([mockColumn]); | ||
const spyGetData = jest.spyOn(gridStub, 'getDataItem').mockReturnValue(mockRowData); | ||
const spyOnChange = jest.spyOn(mockColumn, 'onCellClick'); | ||
|
||
service.bindOnClick(gridStub, dataViewStub); | ||
gridStub.onClick.notify({ cell: 0, row: 0 }, new Slick.EventData(), gridStub); | ||
|
||
expect(spyActive).toHaveBeenCalled(); | ||
expect(spyGetCols).toHaveBeenCalled(); | ||
expect(spyGetData).toHaveBeenCalled(); | ||
expect(spyOnChange).toHaveBeenCalledWith(expect.anything(), { | ||
row: 0, | ||
cell: 0, | ||
dataView: dataViewStub, | ||
grid: gridStub, | ||
columnDef: mockColumn, | ||
dataContext: mockRowData | ||
}); | ||
}); | ||
}); | ||
|
||
describe('dispose method', () => { | ||
it('should unsubscribe all event from the event handler', () => { | ||
const eventHandler = service.eventHandler; | ||
const spy = jest.spyOn(eventHandler, 'unsubscribeAll'); | ||
|
||
service.dispose(); | ||
|
||
expect(spy).toHaveBeenCalled(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import { CellArgs, Column, GridOption, OnEventArgs, SlickEventHandler } from './../interfaces/index'; | ||
|
||
// using external non-typed js libraries | ||
declare const Slick: any; | ||
|
||
export class GridEventService { | ||
private _eventHandler: SlickEventHandler; | ||
|
||
get eventHandler(): SlickEventHandler { | ||
return this._eventHandler; | ||
} | ||
|
||
constructor() { | ||
this._eventHandler = new Slick.EventHandler(); | ||
} | ||
|
||
/* OnCellChange Event */ | ||
bindOnBeforeEditCell(grid: any, dataView: any) { | ||
// subscribe to this Slickgrid event of onBeforeEditCell | ||
this._eventHandler.subscribe(grid.onBeforeEditCell, (e: KeyboardEvent | MouseEvent, args: CellArgs) => { | ||
if (!e || !args || !grid || args.cell === undefined || !grid.getColumns || !grid.getDataItem) { | ||
return; | ||
} | ||
const column: Column = grid.getColumns()[args.cell]; | ||
|
||
// if the column definition has a onBeforeEditCell property (a callback function), then run it | ||
if (typeof column.onBeforeEditCell === 'function') { | ||
// add to the output gridOptions & dataView since we'll need them inside the AJAX column.onBeforeEditCell | ||
const returnedArgs: OnEventArgs = { | ||
row: args.row, | ||
cell: args.cell, | ||
dataView, | ||
grid, | ||
columnDef: column, | ||
dataContext: grid.getDataItem(args.row) | ||
}; | ||
|
||
// finally call up the Slick.column.onBeforeEditCells.... function | ||
column.onBeforeEditCell(e, returnedArgs); | ||
} | ||
}); | ||
} | ||
|
||
/* OnCellChange Event */ | ||
bindOnCellChange(grid: any, dataView: any) { | ||
// subscribe to this Slickgrid event of onCellChange | ||
this._eventHandler.subscribe(grid.onCellChange, (e: KeyboardEvent | MouseEvent, args: CellArgs) => { | ||
if (!e || !args || !grid || args.cell === undefined || !grid.getColumns || !grid.getDataItem) { | ||
return; | ||
} | ||
const column: Column = grid.getColumns()[args.cell]; | ||
|
||
// if the column definition has a onCellChange property (a callback function), then run it | ||
if (typeof column.onCellChange === 'function') { | ||
// add to the output gridOptions & dataView since we'll need them inside the AJAX column.onCellChange | ||
const returnedArgs: OnEventArgs = { | ||
row: args.row, | ||
cell: args.cell, | ||
dataView, | ||
grid, | ||
columnDef: column, | ||
dataContext: grid.getDataItem(args.row) | ||
}; | ||
|
||
// finally call up the Slick.column.onCellChanges.... function | ||
column.onCellChange(e, returnedArgs); | ||
} | ||
}); | ||
} | ||
|
||
/* OnClick Event */ | ||
bindOnClick(grid: any, dataView: any) { | ||
this._eventHandler.subscribe(grid.onClick, (e: KeyboardEvent | MouseEvent, args: CellArgs) => { | ||
if (!e || !args || !grid || args.cell === undefined || !grid.getColumns || !grid.getDataItem) { | ||
return; | ||
} | ||
const column: Column = grid && grid.getColumns && grid.getColumns()[args.cell]; | ||
const gridOptions: GridOption = grid && grid.getOptions && grid.getOptions() || {}; | ||
|
||
// only when using autoCommitEdit, we will make the cell active (in focus) when clicked | ||
// setting the cell as active as a side effect and if autoCommitEdit is set to false then the Editors won't save correctly | ||
if (gridOptions.enableCellNavigation && (!gridOptions.editable || (gridOptions.editable && gridOptions.autoCommitEdit))) { | ||
grid.setActiveCell(args.row, args.cell); | ||
} | ||
|
||
// if the column definition has a onCellClick property (a callback function), then run it | ||
if (typeof column.onCellClick === 'function') { | ||
// add to the output gridOptions & dataView since we'll need them inside the AJAX column.onClick | ||
const returnedArgs: OnEventArgs = { | ||
row: args.row, | ||
cell: args.cell, | ||
dataView, | ||
grid, | ||
columnDef: column, | ||
dataContext: grid.getDataItem(args.row) | ||
}; | ||
|
||
// finally call up the Slick.column.onCellClick.... function | ||
column.onCellClick(e, returnedArgs); | ||
} | ||
}); | ||
} | ||
|
||
dispose() { | ||
this._eventHandler.unsubscribeAll(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.