[Dashboard] Improve duplicate panel positioning (#67461)

* [Dashboard] Clone panel position

* Fixing inconsistencies in previous commit; removing readonly property of a grid

* Change sorting algorithm so that it sorts by the ending coordinates

* Always place panel to the bottom

* Fixing declaration error

* Add more comments

* Make GridData readonly
This commit is contained in:
Maja Grubic 2020-06-05 14:21:17 +01:00 committed by GitHub
parent 20b804e1c3
commit 45107bc480
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -108,16 +108,32 @@ interface IplacementDirection {
fits: boolean;
}
/**
* Compare grid data by an ending y coordinate. Grid data with a smaller ending y coordinate
* comes first.
* @param a
* @param b
*/
function comparePanels(a: GridData, b: GridData): number {
if (a.y + a.h < b.y + b.h) {
return -1;
}
if (a.y + a.h > b.y + b.h) {
return 1;
}
// a.y === b.y
if (a.x + a.w <= b.x + b.w) {
return -1;
}
return 1;
}
export function placePanelBeside({
width,
height,
currentPanels,
placeBesideId,
}: IPanelPlacementBesideArgs): Omit<GridData, 'i'> {
// const clonedPanels = _.cloneDeep(currentPanels);
if (!placeBesideId) {
throw new Error('Place beside method called without placeBesideId');
}
const panelToPlaceBeside = currentPanels[placeBesideId];
if (!panelToPlaceBeside) {
throw new PanelNotFoundError();
@ -130,10 +146,11 @@ export function placePanelBeside({
const possiblePlacementDirections: IplacementDirection[] = [
{ grid: { x: beside.x + beside.w, y: beside.y, w: width, h: height }, fits: true }, // right
{ grid: { x: beside.x - width, y: beside.y, w: width, h: height }, fits: true }, // left
{ grid: { x: 0, y: beside.y + beside.h, w: width, h: height }, fits: true }, // left side of next row
{ grid: { x: beside.x, y: beside.y + beside.h, w: width, h: height }, fits: true }, // bottom
];
// first, we check if there is place around the current panel
for (const direction of possiblePlacementDirections) {
if (
direction.grid.x >= 0 &&
@ -156,13 +173,32 @@ export function placePanelBeside({
}
}
// 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!
const [, , bottomPlacement] = possiblePlacementDirections;
for (const currentPanelGrid of otherPanels) {
if (bottomPlacement.grid.y <= currentPanelGrid.y) {
const movedPanel = _.cloneDeep(currentPanels[currentPanelGrid.i]);
movedPanel.gridData.y = movedPanel.gridData.y + bottomPlacement.grid.h;
currentPanels[currentPanelGrid.i] = movedPanel;
/**
* 1. sort the panels in the grid
* 2. place the cloned panel to the bottom
* 3. reposition the panels after the cloned panel in the grid
*/
const grid = otherPanels.sort(comparePanels);
let position = 0;
for (position; position < grid.length; position++) {
if (beside.i === grid[position].i) {
break;
}
}
const bottomPlacement = possiblePlacementDirections[2];
// place to the bottom and move all other panels
let originalPositionInTheGrid = grid[position + 1].i;
const diff =
bottomPlacement.grid.y +
bottomPlacement.grid.h -
currentPanels[originalPositionInTheGrid].gridData.y;
for (let j = position + 1; j < grid.length; j++) {
originalPositionInTheGrid = grid[j].i;
const movedPanel = _.cloneDeep(currentPanels[originalPositionInTheGrid]);
movedPanel.gridData.y = movedPanel.gridData.y + diff;
currentPanels[originalPositionInTheGrid] = movedPanel;
}
return bottomPlacement.grid;
}