-
Notifications
You must be signed in to change notification settings - Fork 8.5k
[8.19] Fix Save Modal promise chain onSave (#233933)
#234498
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
[8.19] Fix Save Modal promise chain onSave (#233933)
#234498
Conversation
## Summary This PR fixes an issue in which the SO save modal in Lens, Dashboard and others, allowed the user to spam the save button, resulting in multiple saved instances. ### Demo #### Before https://github.com/user-attachments/assets/70ddc6c1-b99d-4758-8333-fe9ab47474a4 #### After https://github.com/user-attachments/assets/84f016dd-05d9-441c-864c-b06160c9d531 Fixes elastic#233906 ## Details When attempting to save any SO using the [`SavedObjectSaveModal`](https://github.com/elastic/kibana/blob/07cc9e9c1a271c37f42c84f57a1600596070fd9c/src/platform/plugins/shared/saved_objects/public/save_modal/saved_object_save_modal.tsx#L95), the logic was attempting to `await` the call to `onSave` and block any additional calls. This was working correctly to set the `isLoading` state, but the `onSave` callback is not expecting a `Promise` to be returned so it has no affect and the `onSave` is immediately resolved, unsetting the loading state and thus allowing multiple calls to save. So the issue is that `onSave` should expect `() => Promise<void>` not `() => void`. A crude fix to this could be to throttle the calls to `onSave` and preventing and future clicks until the save is eventually complete. But if the save takes longer or fails this will enable the save button and allow clicking again, creating other possible issues and not solving the root of the problem. So the chain of `onSave` is broken from calling it here to the eventual function up the call stack that is performing the save. This involves updating the chain of promised from the `onSave` prop all the way up to the root consumer, which is typically calling an async function. Further complicating things.... there is this dreadful, I mean deprecated, `showSaveModal` function that wraps a modal component (almost like a HOC) and calls `props.onSave` of the passed component to determine the success state of the call to `onSave`. https://github.com/elastic/kibana/blob/07cc9e9c1a271c37f42c84f57a1600596070fd9c/src/platform/plugins/shared/saved_objects/public/save_modal/show_saved_object_save_modal.tsx#L34-L37 Here's a rough example... ```tsx import { showSaveModal } from "@kbn/saved-objects-plugin/public"; export function openSaveModal() { // ... showSaveModal( <SavedObjectSaveModal ... onSave={async () => { const response = await doTheSave(); if(response.success) { return { id: response.id }; } else { return { error: 'failed to save' } } }} /> ); } ``` The strange thing is that the `SavedObjectSaveModal.onSave` doesn't need the `SaveResult` to be returned and these modal components are used in various places but only some are passed to `showSaveModal`. So I cleaned up this code as well to expect the `SaveResult` when using `showSaveModal` and `void` otherwise. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [x] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ## Release Notes Fixes issue with save modal allowing duplicate saves of dashboard, visualizations and others. --------- Co-authored-by: Marco Vettorello <[email protected]> Co-authored-by: Davis McPhee <[email protected]> (cherry picked from commit 8415158) # Conflicts: # src/platform/plugins/private/links/public/content_management/save_to_library.tsx # src/platform/plugins/shared/dashboard/public/dashboard_actions/library_add_action.tsx # src/platform/plugins/shared/discover/public/application/main/components/top_nav/save_discover_session/save_modal.tsx # src/platform/plugins/shared/saved_objects/public/save_modal/saved_object_save_modal.test.tsx # src/platform/plugins/shared/saved_objects/public/save_modal/saved_object_save_modal.tsx # src/platform/plugins/shared/saved_objects/public/save_modal/saved_object_save_modal_origin.tsx # src/platform/plugins/shared/saved_objects/public/save_modal/show_saved_object_save_modal.tsx # src/platform/plugins/shared/visualizations/public/legacy/embeddable/attribute_service.tsx # src/platform/plugins/shared/visualizations/public/visualize_app/utils/get_top_nav_config.tsx # x-pack/platform/plugins/private/graph/public/components/save_modal.tsx # x-pack/platform/plugins/shared/maps/public/routes/map_page/top_nav_config.tsx
|
Pinging @elastic/obs-ux-management-team (Team:obs-ux-management) |
|
Pinging @elastic/kibana-visualizations (Team:Visualizations) |
💚 Build Succeeded
Metrics [docs]Module Count
Public APIs missing comments
Async chunks
Page load bundle
Unknown metric groupsAPI count
async chunk count
ESLint disabled line counts
References to deprecated APIs
Total ESLint disabled count
History
|
Backport
This will backport the following commits from
mainto8.19:onSave(#233933)Questions ?
Please refer to the Backport tool documentation