@@ -102,55 +102,89 @@ export function findTopLeftMostOpenSpace({
102102 return { x : 0 , y : maxY , w : width , h : height } ;
103103}
104104
105+ interface IplacementDirection {
106+ grid : Omit < GridData , 'i' > ;
107+ fits : boolean ;
108+ }
109+
105110export function placePanelBeside ( {
106111 width,
107112 height,
108113 currentPanels,
109114 placeBesideId,
110115} : IPanelPlacementBesideArgs ) : Omit < GridData , 'i' > {
111- const finalPanels = _ . cloneDeep ( currentPanels ) ;
116+ // const clonedPanels = _.cloneDeep(currentPanels);
112117 if ( ! placeBesideId ) {
113118 throw new Error ( 'Place beside method called without placeBesideId' ) ;
114119 }
115- const panelToPlaceBeside = finalPanels [ placeBesideId ] ;
120+ const panelToPlaceBeside = currentPanels [ placeBesideId ] ;
116121 if ( ! panelToPlaceBeside ) {
117122 throw new PanelNotFoundError ( ) ;
118123 }
119-
120- const duplicatedPanelGrid = { } as GridData ;
121- duplicatedPanelGrid . x = panelToPlaceBeside . gridData . x + panelToPlaceBeside . gridData . w ;
122- duplicatedPanelGrid . y = panelToPlaceBeside . gridData . y ;
123- duplicatedPanelGrid . w = width ;
124- duplicatedPanelGrid . h = height ;
125-
126- // Adjust flow of dashboard if necessary
124+ const beside = panelToPlaceBeside . gridData ;
127125 const otherPanels : GridData [ ] = [ ] ;
128- _ . forOwn ( finalPanels , ( panel : DashboardPanelState ) => {
129- if ( panel . savedObjectId !== panelToPlaceBeside . savedObjectId ) {
130- otherPanels . push ( panel . gridData ) ;
131- }
132- } ) ;
133-
134- const intersection = otherPanels . some ( ( currentPanelGrid : GridData ) => {
135- return (
136- duplicatedPanelGrid . x + duplicatedPanelGrid . w > currentPanelGrid . x &&
137- duplicatedPanelGrid . x < currentPanelGrid . x + currentPanelGrid . w &&
138- duplicatedPanelGrid . y < currentPanelGrid . y + currentPanelGrid . h &&
139- duplicatedPanelGrid . y + duplicatedPanelGrid . h > currentPanelGrid . y
140- ) ;
126+ _ . forOwn ( currentPanels , ( panel : DashboardPanelState , key : string | undefined ) => {
127+ otherPanels . push ( panel . gridData ) ;
141128 } ) ;
142129
143- // if any other panel intersects with the newly duplicated panel, move all panels in the same 'row' to the right by the amount of the duplciated panel's width
144- if ( intersection ) {
130+ const possiblePlacementDirections : IplacementDirection [ ] = [
131+ { grid : { x : beside . x + beside . w , y : beside . y , w : width , h : height } , fits : true } , // right
132+ { grid : { x : beside . x - width , y : beside . y , w : width , h : height } , fits : true } , // left
133+ { grid : { x : beside . x , y : beside . y + beside . h , w : width , h : height } , fits : true } , // bottom
134+ ] ;
135+
136+ for ( const direction of possiblePlacementDirections ) {
137+ if (
138+ direction . grid . x >= 0 &&
139+ direction . grid . x + direction . grid . w <= DASHBOARD_GRID_COLUMN_COUNT &&
140+ direction . grid . y >= 0
141+ ) {
142+ const intersection = otherPanels . some ( ( currentPanelGrid : GridData ) => {
143+ return (
144+ direction . grid . x + direction . grid . w > currentPanelGrid . x &&
145+ direction . grid . x < currentPanelGrid . x + currentPanelGrid . w &&
146+ direction . grid . y < currentPanelGrid . y + currentPanelGrid . h &&
147+ direction . grid . y + direction . grid . h > currentPanelGrid . y
148+ ) ;
149+ } ) ;
150+ if ( ! intersection ) {
151+ return direction . grid ;
152+ }
153+ } else {
154+ direction . fits = false ;
155+ }
156+ }
157+ // if we get here that means there is no blank space around the panel we are placing beside. This means it's time to mess up the dashboard's groove. Fun!
158+ const [ rightPlacement , , bottomPlacement ] = possiblePlacementDirections ;
159+ if ( rightPlacement . fits ) {
145160 otherPanels . forEach ( ( currentPanelGrid : GridData ) => {
146161 if (
147- currentPanelGrid . x >= duplicatedPanelGrid . x &&
148- duplicatedPanelGrid . y <= currentPanelGrid . y + currentPanelGrid . h &&
149- duplicatedPanelGrid . y + duplicatedPanelGrid . h >= currentPanelGrid . y
162+ currentPanelGrid . x >= rightPlacement . grid . x &&
163+ rightPlacement . grid . y < currentPanelGrid . y + currentPanelGrid . h &&
164+ rightPlacement . grid . y + rightPlacement . grid . h > currentPanelGrid . y
150165 ) {
151- currentPanelGrid . x += duplicatedPanelGrid . w ;
166+ const movedPanel = _ . cloneDeep ( currentPanels [ currentPanelGrid . i ] ) ;
167+ if ( movedPanel . gridData . x + rightPlacement . grid . w > DASHBOARD_GRID_COLUMN_COUNT ) {
168+ movedPanel . gridData . y = movedPanel . gridData . y + rightPlacement . grid . h ;
169+ } else {
170+ movedPanel . gridData . x = movedPanel . gridData . x + rightPlacement . grid . w ;
171+ }
172+ currentPanels [ currentPanelGrid . i ] = movedPanel ;
152173 }
153174 } ) ;
175+ return rightPlacement . grid ;
176+ }
177+ for ( const currentPanelGrid of otherPanels ) {
178+ if (
179+ bottomPlacement . grid . x + bottomPlacement . grid . w > currentPanelGrid . x &&
180+ bottomPlacement . grid . x < currentPanelGrid . x + currentPanelGrid . w &&
181+ bottomPlacement . grid . y < currentPanelGrid . y + currentPanelGrid . h &&
182+ bottomPlacement . grid . y + bottomPlacement . grid . h > currentPanelGrid . y
183+ ) {
184+ const movedPanel = _ . cloneDeep ( currentPanels [ currentPanelGrid . i ] ) ;
185+ movedPanel . gridData . y = movedPanel . gridData . y + bottomPlacement . grid . h ;
186+ currentPanels [ currentPanelGrid . i ] = movedPanel ;
187+ }
154188 }
155- return duplicatedPanelGrid ;
189+ return bottomPlacement . grid ;
156190}
0 commit comments