diff --git a/frontend/src/views/dashboard/canvas/CanvasCore.vue b/frontend/src/views/dashboard/canvas/CanvasCore.vue index 89f2acee..d1545078 100644 --- a/frontend/src/views/dashboard/canvas/CanvasCore.vue +++ b/frontend/src/views/dashboard/canvas/CanvasCore.vue @@ -1063,6 +1063,8 @@ const forceComputed = () => { } function addItemBox(item: CanvasItem) { + // @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment + item.x = findPositionX(item) canvasComponentData.value.push(item) forceComputed() nextTick(() => { @@ -1166,6 +1168,49 @@ function tabMoveInCheckSQ() { } } +/** + * Find position box + */ +function findPositionX(item: CanvasItem) { + const width = item.sizeX + let resultX = 1 + let checkPointYIndex = -1 // -1 means not occupying any Y-direction canvas + // Component width + let pb = positionBox.value + if (width <= 0) return + // Find the highest position index of the component. Component rule: the latest y is 1. + canvasComponentData.value.forEach((component) => { + const componentYIndex = component.y + component.sizeY - 2 + if (checkPointYIndex < componentYIndex) { + checkPointYIndex = componentYIndex + } + }) + // Start checking from index i in the X direction; + const pbX = pb[checkPointYIndex] + // Get the last column array in the X direction + if (checkPointYIndex < 0 || !pbX) { + return 1 + } else { + // The width to check is the component width. The end index of the check is checkEndIndex = i + width - 1; + // The exit condition for the check is when the end index checkEndIndex is out of bounds (exceeds the end index of pbX). + for (let i = 0, checkEndIndex = width - 1; checkEndIndex < pbX.length; i++, checkEndIndex++) { + let adaptorCount = 0 + // Locate the occupied position in the last column + for (let k = 0; k < width; k++) { + // pbX[i + k].el === false indicates that the current matrix point is not occupied. When the width of consecutive unoccupied matrix points equals the component width, the starting point i is available. + if (!pbX[i + k].el) { + adaptorCount++ + } + } + if (adaptorCount === width) { + resultX = i + 1 + break + } + } + return resultX + } +} + useEmitt({ name: `editor-delete-${props.canvasId}`, callback: removeItemById, diff --git a/frontend/src/views/dashboard/editor/index.vue b/frontend/src/views/dashboard/editor/index.vue index b8256625..34f7b248 100644 --- a/frontend/src/views/dashboard/editor/index.vue +++ b/frontend/src/views/dashboard/editor/index.vue @@ -40,12 +40,23 @@ const addComponent = (componentType: string, viewInfo?: any) => { component.propValue[0].title = t('dashboard.new_tab') component.activeTabName = subTabName } - component.y = 100 + component.y = maxYComponentCount() + 10 // @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment dashboardEditorInnerRef.value.addItemToBox(component) } } +const maxYComponentCount = () => { + if (componentData.value.length === 0) { + return 1 + } else { + return componentData.value + .filter((item) => item['y']) + .map((item) => item['y'] + item['sizeY']) // Calculate the y+sizeY of each element + .reduce((max, current) => Math.max(max, current), 0) + } +} + onMounted(() => { // @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment state.opt = router.currentRoute.value.query.opt