Skip to content

Commit

Permalink
feat(editor): auto commit before save; add onBeforeEditMode callback (
Browse files Browse the repository at this point in the history
#1353)

* feat: add onBeforeEditMode callback

* feat: should auto-commit any current changes before save
  • Loading branch information
zewa666 authored Jan 19, 2024
1 parent e5e29c0 commit f33bf52
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 3 deletions.
3 changes: 2 additions & 1 deletion docs/grid-functionalities/Row-based-edit.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<boolean>`. 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<boolean>`. 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:

Expand Down
3 changes: 1 addition & 2 deletions examples/vite-demo-vanilla-bundle/src/examples/example22.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
24 changes: 24 additions & 0 deletions packages/common/src/extensions/__tests__/slickRowBasedEdit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}),
Expand Down Expand Up @@ -626,6 +632,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' };
Expand Down
8 changes: 8 additions & 0 deletions packages/common/src/extensions/slickRowBasedEdit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) ||
Expand All @@ -369,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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<boolean>;

/** method called before a row enters edit mode. */
onBeforeEditMode?: (args: OnEventArgs) => void;
}
8 changes: 8 additions & 0 deletions test/cypress/e2e/example22.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down

0 comments on commit f33bf52

Please sign in to comment.