From bb94b053f1ebf2993690e1d2d1686ff65a1166bf Mon Sep 17 00:00:00 2001 From: Vildan Softic Date: Fri, 19 Jan 2024 21:55:20 +0100 Subject: [PATCH 1/2] feat: add onBeforeEditMode callback --- docs/grid-functionalities/Row-based-edit.md | 3 ++- .../src/examples/example22.ts | 3 +-- .../__tests__/slickRowBasedEdit.spec.ts | 18 ++++++++++++++++++ .../common/src/extensions/slickRowBasedEdit.ts | 4 ++++ .../interfaces/rowBasedEditOption.interface.ts | 3 +++ test/cypress/e2e/example22.cy.ts | 8 ++++++++ 6 files changed, 36 insertions(+), 3 deletions(-) diff --git a/docs/grid-functionalities/Row-based-edit.md b/docs/grid-functionalities/Row-based-edit.md index 133d91118..4ef9740e1 100644 --- a/docs/grid-functionalities/Row-based-edit.md +++ b/docs/grid-functionalities/Row-based-edit.md @@ -30,7 +30,8 @@ You can override the styling, the hover text as well as whether a prompt — and If the [Excel Copy Buffer Plugin](excel-copy-buffer.md) is configured, the Row based editing pluging will override it's behavior by denying pastes on all cells not within a edit mode row. Nevertheless, any existing `BeforePasteCellHandler` will be respected. ## How the plugin works -The idea of the plugin is to focus the users editing experience on specific individual rows and and save them individually. This is achieved by letting the user toggle one or more rows into edit mode. Now changes can be made to those rows and will be highlighted and tracked. The user may cancel the edit mode at any time and revert all cells changes. If the save button is pressed on the other hand an `onBeforeRowUpdated` hook, which you define via plugin options, is called and expects a `Promise`. In that method you'd typically write the changes to your backend and return either true or false based on the operations outcome. If a negative boolean is returned the edit mode is kept, otherwise the row applies the changes and toggles back into readonly mode. That means, no modifications can be done on the grid. +The idea of the plugin is to focus the users editing experience on specific individual rows and and save them individually. This is achieved by letting the user toggle one or more rows into edit mode. +When a that happens a potentially registered `onBeforeEditMode` callback is executed to handle various preparation or cleanup tasks. Now changes can be made to those rows and will be highlighted and tracked. The user may cancel the edit mode at any time and revert all cells changes. If the save button is pressed on the other hand an `onBeforeRowUpdated` hook, which you define via plugin options, is called and expects a `Promise`. In that method you'd typically write the changes to your backend and return either true or false based on the operations outcome. If a negative boolean is returned the edit mode is kept, otherwise the row applies the changes and toggles back into readonly mode. That means, no modifications can be done on the grid. Here's the respective code shown in Example22: diff --git a/examples/vite-demo-vanilla-bundle/src/examples/example22.ts b/examples/vite-demo-vanilla-bundle/src/examples/example22.ts index 48c479ca5..1bbf88cc3 100644 --- a/examples/vite-demo-vanilla-bundle/src/examples/example22.ts +++ b/examples/vite-demo-vanilla-bundle/src/examples/example22.ts @@ -135,8 +135,8 @@ export default class Example22 { enableRowBasedEdit: true, rowBasedEditOptions: { allowMultipleRows: false, + onBeforeEditMode: () => this.clearStatus(), onBeforeRowUpdated: (args) => { - this.clearStatus(); const { effortDriven, percentComplete, finish, start, duration, title } = args.dataContext; if (duration > 40) { @@ -164,7 +164,6 @@ export default class Example22 { } }) .then(json => { - // alert(json.message); this.statusStyle = 'display: block'; this.statusClass = 'notification is-light is-success'; this.fetchResult = json.message; diff --git a/packages/common/src/extensions/__tests__/slickRowBasedEdit.spec.ts b/packages/common/src/extensions/__tests__/slickRowBasedEdit.spec.ts index 67f112615..1867a0c12 100644 --- a/packages/common/src/extensions/__tests__/slickRowBasedEdit.spec.ts +++ b/packages/common/src/extensions/__tests__/slickRowBasedEdit.spec.ts @@ -626,6 +626,24 @@ describe('Row Based Edit Plugin', () => { expect(gridStub.invalidate).toHaveBeenCalledTimes(1); }); + it('should call an optionally registered onBeforeEditMode callback clicking the edit button', () => { + const spy = jest.fn(); + const { onCellClick } = arrange({ onBeforeEditMode: () => spy() }); + const fakeItem = { id: 'test' }; + + gridStub.invalidate.mockClear(); + onCellClick(createFakeEvent(BTN_ACTION_EDIT), { + row: 0, + cell: 0, + grid: gridStub, + columnDef: {} as Column, + dataContext: fakeItem, + dataView: gridStub.getData(), + }); + + expect(spy).toHaveBeenCalled(); + }); + it('should not enter editmode when not in allowMultipleRows mode and a previous row is already in editmode', () => { const { onCellClick } = arrange(); const fakeItem = { id: 'test' }; diff --git a/packages/common/src/extensions/slickRowBasedEdit.ts b/packages/common/src/extensions/slickRowBasedEdit.ts index 5b7c0bd48..e583fe5d9 100644 --- a/packages/common/src/extensions/slickRowBasedEdit.ts +++ b/packages/common/src/extensions/slickRowBasedEdit.ts @@ -356,6 +356,10 @@ export class SlickRowBasedEdit { return; } + if (typeof this._addonOptions?.onBeforeEditMode === 'function') { + this._addonOptions.onBeforeEditMode!(args); + } + this.toggleEditmode(dataContext, true); } else if ( target.classList.contains(BTN_ACTION_UPDATE) || diff --git a/packages/common/src/interfaces/rowBasedEditOption.interface.ts b/packages/common/src/interfaces/rowBasedEditOption.interface.ts index 5a14dbd85..57d7248aa 100644 --- a/packages/common/src/interfaces/rowBasedEditOption.interface.ts +++ b/packages/common/src/interfaces/rowBasedEditOption.interface.ts @@ -69,4 +69,7 @@ export interface RowBasedEditOptions { /** method called before row gets updated. Needs to return a promised boolean. True will continue; False will halt the update */ onBeforeRowUpdated?: (args: OnEventArgs) => Promise; + + /** method called before a row enters edit mode. */ + onBeforeEditMode?: (args: OnEventArgs) => void; } \ No newline at end of file diff --git a/test/cypress/e2e/example22.cy.ts b/test/cypress/e2e/example22.cy.ts index c4174f863..7f926a5d6 100644 --- a/test/cypress/e2e/example22.cy.ts +++ b/test/cypress/e2e/example22.cy.ts @@ -96,6 +96,14 @@ describe('Example 22 - Row Based Editing', () => { cy.get('.slick-cell.l2.r2').first().should('contain', '30'); }); + it('should cleanup status when starting a new edit mode', () => { + cy.get('.action-btns--edit').first().click(); + + cy.get('[data-test="fetch-result"]').should('be.empty'); + + cy.get('.action-btns--cancel').first().click(); + }); + it('should revert changes on cancel click', () => { cy.get('.action-btns--edit').first().click(); From 3d28765c527ab0c43abf52f777bab5f2e9157eac Mon Sep 17 00:00:00 2001 From: Vildan Softic Date: Fri, 19 Jan 2024 22:11:26 +0100 Subject: [PATCH 2/2] feat: should auto-commit any current changes before save --- .../src/extensions/__tests__/slickRowBasedEdit.spec.ts | 6 ++++++ packages/common/src/extensions/slickRowBasedEdit.ts | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/packages/common/src/extensions/__tests__/slickRowBasedEdit.spec.ts b/packages/common/src/extensions/__tests__/slickRowBasedEdit.spec.ts index 1867a0c12..f50f0bb2a 100644 --- a/packages/common/src/extensions/__tests__/slickRowBasedEdit.spec.ts +++ b/packages/common/src/extensions/__tests__/slickRowBasedEdit.spec.ts @@ -65,6 +65,12 @@ const gridStubBlueprint = { registerPlugin: jest.fn(), onSetOptions: new SlickEvent(), onBeforeEditCell: new SlickEvent(), + getEditController: jest.fn().mockReturnValue({ + commitCurrentEdit: jest.fn(), + cancelCurrentEdit: jest.fn(), + }), + getCellEditor: jest.fn().mockReturnValue({}), + getActiveCell: jest.fn().mockReturnValue({ row: 0, cell: 0}), setColumns: jest.fn().mockImplementation((columns) => { (gridStubBlueprint as any).columns = columns; }), diff --git a/packages/common/src/extensions/slickRowBasedEdit.ts b/packages/common/src/extensions/slickRowBasedEdit.ts index e583fe5d9..16ae530c8 100644 --- a/packages/common/src/extensions/slickRowBasedEdit.ts +++ b/packages/common/src/extensions/slickRowBasedEdit.ts @@ -373,6 +373,10 @@ export class SlickRowBasedEdit { return; } + if (this._grid.getCellEditor() && this._grid.getActiveCell()?.row === args.row) { + this._grid.getEditController()?.commitCurrentEdit(); + } + if (this._addonOptions?.onBeforeRowUpdated) { const result = await this._addonOptions.onBeforeRowUpdated(args);