@@ -14,7 +14,7 @@ import type {
1414 ReactComponentConfig ,
1515} from '@deephaven/golden-layout' ;
1616import Log from '@deephaven/log' ;
17- import { usePrevious } from '@deephaven/react-hooks' ;
17+ import { usePrevious , useThrottledCallback } from '@deephaven/react-hooks' ;
1818import { RootState } from '@deephaven/redux' ;
1919import { useDispatch , useSelector } from 'react-redux' ;
2020import PanelManager , { ClosedPanels } from './PanelManager' ;
@@ -46,6 +46,8 @@ const DEFAULT_LAYOUT_CONFIG: DashboardLayoutConfig = [];
4646
4747const DEFAULT_CALLBACK = ( ) : void => undefined ;
4848
49+ const STATE_CHANGE_THROTTLE_MS = 1000 ;
50+
4951// If a component isn't registered, just pass through the props so they are saved if a plugin is loaded later
5052const FALLBACK_CALLBACK = ( props : unknown ) : unknown => props ;
5153
@@ -195,6 +197,34 @@ export function DashboardLayout({
195197 ]
196198 ) ;
197199
200+ // Throttle the calls so that we don't flood comparing these layouts
201+ const throttledProcessDehydratedLayoutConfig = useThrottledCallback (
202+ ( dehydratedLayoutConfig : DashboardLayoutConfig ) => {
203+ const hasChanged =
204+ lastConfig == null ||
205+ ! LayoutUtils . isEqual ( lastConfig , dehydratedLayoutConfig ) ;
206+
207+ log . debug ( 'handleLayoutStateChanged' , hasChanged , dehydratedLayoutConfig ) ;
208+
209+ if ( hasChanged ) {
210+ setIsDashboardEmpty ( layout . root . contentItems . length === 0 ) ;
211+
212+ setLastConfig ( dehydratedLayoutConfig ) ;
213+
214+ onLayoutChange ( dehydratedLayoutConfig ) ;
215+
216+ setLayoutChildren ( layout . getReactChildren ( ) ) ;
217+ }
218+ } ,
219+ STATE_CHANGE_THROTTLE_MS ,
220+ { flushOnUnmount : true }
221+ ) ;
222+
223+ useEffect (
224+ ( ) => ( ) => throttledProcessDehydratedLayoutConfig . flush ( ) ,
225+ [ throttledProcessDehydratedLayoutConfig ]
226+ ) ;
227+
198228 const handleLayoutStateChanged = useCallback ( ( ) => {
199229 // we don't want to emit stateChanges that happen during item drags or else
200230 // we risk the last saved state being one without that panel in the layout entirely
@@ -206,27 +236,13 @@ export function DashboardLayout({
206236 contentConfig ,
207237 dehydrateComponent
208238 ) ;
209- const hasChanged =
210- lastConfig == null ||
211- ! LayoutUtils . isEqual ( lastConfig , dehydratedLayoutConfig ) ;
212-
213- log . debug (
214- 'handleLayoutStateChanged' ,
215- hasChanged ,
216- contentConfig ,
217- dehydratedLayoutConfig
218- ) ;
219-
220- if ( hasChanged ) {
221- setIsDashboardEmpty ( layout . root . contentItems . length === 0 ) ;
222-
223- setLastConfig ( dehydratedLayoutConfig ) ;
224-
225- onLayoutChange ( dehydratedLayoutConfig ) ;
226-
227- setLayoutChildren ( layout . getReactChildren ( ) ) ;
228- }
229- } , [ dehydrateComponent , isItemDragging , lastConfig , layout , onLayoutChange ] ) ;
239+ throttledProcessDehydratedLayoutConfig ( dehydratedLayoutConfig ) ;
240+ } , [
241+ dehydrateComponent ,
242+ isItemDragging ,
243+ layout ,
244+ throttledProcessDehydratedLayoutConfig ,
245+ ] ) ;
230246
231247 const handleLayoutItemPickedUp = useCallback (
232248 ( component : Container ) => {
0 commit comments