Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(editor): auto commit before save; add onBeforeEditMode callback #1353

Merged
merged 2 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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