[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:
parent
20b804e1c3
commit
45107bc480
1 changed files with 47 additions and 11 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue