vaadin / flow-components

Java counterpart of Vaadin Web Components
101 stars 66 forks source link

[Crud] Allow cancellation of save event and dialog closing #6163

Open stefanuebe opened 7 months ago

stefanuebe commented 7 months ago

Describe your motivation

Currently it is not possible to stop the save process of the crud (i.e. prevent the dialog from being closed), when the user clicked the save button. This makes it impossible to react to potential issues when saving the edited item in the backend (db errors, that cannot be checked beforehand).

Describe the solution you'd like

It should be possible to cancel the save event in some way, e.g. by a new method "SaveEvent#cancelSave()" or similar. When cancelled, the crud editor should stay open.

Describe alternatives you've considered

EnhancedCrud is unfortunately not officially built for V24. Using the binder is also not a viable option, since the feedback is given by the database. The only alternative we have considered is overriding the default save handling using some quick and dirty workarounds.

Additional context

No response

stefanuebe commented 7 months ago

Side note: throwing an exception and handling it in the Vaadin Error Handler seems to work. Not the best solution as it bleeds editor details into the error handler, but prevents the dev from having to hack internal things.

private void initCrud() {
    // ...    
    crud.addSaveListener(event -> {
        try {
            database.persist(event.getItem());
        } catch (DatabaseException e) {
            throw new EditorSaveException(e.getMessage());
        }
    });
    // ...
}

public static final class EditorSaveException extends RuntimeException {
    public EditorSaveException(String message) {
        super(message);
    }
}
@SpringComponent
public class MyServiceInit implements VaadinServiceInitListener {
    @Override
    public void serviceInit(ServiceInitEvent event) {
        VaadinService source = event.getSource();
        source.addSessionInitListener(sessionInitEvent -> {
            sessionInitEvent.getSession().setErrorHandler(errorEvent -> {
                Throwable throwable = errorEvent.getThrowable();
                if (throwable instanceof EditorSaveException editorSaveException) {
                    Notification.show(editorSaveException.getMessage()).addThemeVariants(NotificationVariant.LUMO_ERROR);
                }
            });
        });
    }
}
TatuLund commented 7 months ago

We had this in Enhanced CRUD as PreSaveEvent:

https://github.com/vaadin-component-factory/enhanced-crud/blob/master/enhanced-crud-flow/src/main/java/com/vaadin/componentfactory/enhancedcrud/Crud.java#L630

The typical use case was to allow doing some after validation checks when save button has been clicked and option to call cancelSave if needed.