Skip to content

Commit

Permalink
[Embeddables Rebuild] Fix unsaved changes on new dashboards bug (#184955
Browse files Browse the repository at this point in the history
)

Closes #184174

## Summary

This PR fixes the bug where, on a new and unsaved dashboard, adding both
a legacy embeddable and an image embeddable would result in a dashboard
getting stuck with unsaved changes on the first save. This was caused by
a race condition - since the `debounce` on the React embeddable unsaved
changes observable was **before** the `switchMap`, the React embeddable
observable fired **immediately** on save which then triggered the
`diffingSubscription` to fire too early.

**Before:**



https://github.com/elastic/kibana/assets/8698078/44be114a-0c6d-4f40-a5c1-c05889d53ace



**After:**


https://github.com/elastic/kibana/assets/8698078/52f50fd4-0e8f-4aff-8fe6-19b9038623ee
  • Loading branch information
Heenawter committed Jun 6, 2024
1 parent cb2345a commit a4cd614
Showing 1 changed file with 8 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ export function startDiffingDashboardState(
const reactEmbeddableUnsavedChanges = this.children$.pipe(
map((children) => Object.keys(children)),
distinctUntilChanged(deepEqual),
debounceTime(CHANGE_CHECK_DEBOUNCE),

// children may change, so make sure we subscribe/unsubscribe with switchMap
switchMap((newChildIds: string[]) => {
Expand All @@ -107,6 +106,7 @@ export function startDiffingDashboardState(
)
);
}),
debounceTime(CHANGE_CHECK_DEBOUNCE),
map((children) => children.filter((child) => Boolean(child.unsavedChanges)))
);

Expand All @@ -118,18 +118,17 @@ export function startDiffingDashboardState(
startWith(null),
debounceTime(CHANGE_CHECK_DEBOUNCE),
switchMap(() => {
return new Observable<Partial<DashboardContainerInput>>((observer) => {
return (async () => {
const {
explicitInput: currentInput,
componentState: { lastSavedInput },
} = this.getState();
getDashboardUnsavedChanges
.bind(this)(lastSavedInput, currentInput)
.then((unsavedChanges) => {
if (observer.closed) return;
observer.next(unsavedChanges);
});
});
const unsavedChanges = await getDashboardUnsavedChanges.bind(this)(
lastSavedInput,
currentInput
);
return unsavedChanges;
})();
})
);

Expand Down

0 comments on commit a4cd614

Please sign in to comment.