From e9d3f200892d2f3f44d8301a607d4d076956b2d4 Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Tue, 2 Sep 2025 22:48:23 +0800 Subject: [PATCH 1/4] refactor: Optimize the logic for adding charts to the dashboard --- frontend/src/views/chat/chat-block/ChartBlock.vue | 2 +- .../views/dashboard/common/AddViewDashboard.vue | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/frontend/src/views/chat/chat-block/ChartBlock.vue b/frontend/src/views/chat/chat-block/ChartBlock.vue index 6cb35b750..f589fc417 100644 --- a/frontend/src/views/chat/chat-block/ChartBlock.vue +++ b/frontend/src/views/chat/chat-block/ChartBlock.vue @@ -395,7 +395,7 @@ watch( -
+
diff --git a/frontend/src/views/dashboard/common/AddViewDashboard.vue b/frontend/src/views/dashboard/common/AddViewDashboard.vue index 3ae3c3491..2070de5f9 100644 --- a/frontend/src/views/dashboard/common/AddViewDashboard.vue +++ b/frontend/src/views/dashboard/common/AddViewDashboard.vue @@ -20,7 +20,6 @@ const optInit = (viewInfo: any) => { resourceDialogShow.value = true state.viewInfo = viewInfo } -const curOptDashboardId = ref(null) const state = reactive({ dashboardList: [] as SQTreeNode[], viewInfo: null, @@ -127,20 +126,19 @@ const saveResourcePrepare = () => { const saveResource = (params: any, commonParams: any) => { saveDashboardResourceTarget(params, commonParams, (res: any) => { const messageTips = t('dashboard.add_success') - curOptDashboardId.value = res?.id - openMessageLoading(messageTips, 'success', callbackExportSuc) + openMessageLoading(messageTips, 'success', res?.id, callbackExportSuc) resetForm() }) } -const callbackExportSuc = () => { +const callbackExportSuc = (curOptDashboardIdValue: any) => { // do open dashboard - const url = `#/canvas?resourceId=${curOptDashboardId.value}` + const url = `#/canvas?resourceId=${curOptDashboardIdValue}` window.open(url, '_self') } // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type -const openMessageLoading = (text: string, type = 'success', cb: Function) => { +const openMessageLoading = (text: string, type = 'success', dvId: any, cb: Function) => { // success error loading const customClass = `sq-message-${type || 'success'} sq-message-export` ElMessage({ @@ -161,7 +159,7 @@ const openMessageLoading = (text: string, type = 'success', cb: Function) => { size: 'small', class: 'btn-text', onClick: () => { - cb() + cb(dvId) }, }, t('dashboard.open_dashboard') @@ -169,7 +167,7 @@ const openMessageLoading = (text: string, type = 'success', cb: Function) => { ]), type, showClose: true, - duration: 0, + duration: 2000, customClass, }) } From 8d52debc330262f1d78bcd787503943f4fa7684f Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Tue, 2 Sep 2025 22:54:31 +0800 Subject: [PATCH 2/4] refactor: Support adding the modified chart with retained type to the dashboard --- frontend/src/views/chat/chat-block/ChartBlock.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/views/chat/chat-block/ChartBlock.vue b/frontend/src/views/chat/chat-block/ChartBlock.vue index f589fc417..a0553e8a3 100644 --- a/frontend/src/views/chat/chat-block/ChartBlock.vue +++ b/frontend/src/views/chat/chat-block/ChartBlock.vue @@ -216,7 +216,7 @@ function addToDashboard() { // @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment const chartBaseInfo = JSON.parse(props.message?.record?.chart) recordeInfo['chart'] = { - type: chartBaseInfo.type, + type: currentChartType.value, title: chartBaseInfo.title, columns: chartBaseInfo.columns, xAxis: chartBaseInfo.axis?.x ? [chartBaseInfo.axis.x] : [], From 10a00510a9332469e2aa267e47a0e0de4404d960 Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Tue, 2 Sep 2025 23:25:24 +0800 Subject: [PATCH 3/4] refactor: Optimize dashboard name storage, enter key automatically saves --- frontend/src/views/dashboard/editor/Toolbar.vue | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/src/views/dashboard/editor/Toolbar.vue b/frontend/src/views/dashboard/editor/Toolbar.vue index 1dc3c649c..4dc96031a 100644 --- a/frontend/src/views/dashboard/editor/Toolbar.vue +++ b/frontend/src/views/dashboard/editor/Toolbar.vue @@ -91,6 +91,10 @@ const editCanvasName = () => { nameInput.value?.focus() }) } +const handleEnterEditCanvasName = (event: Event) => { + // @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment + event.target?.blur() +} const closeEditCanvasName = () => { nameEdit.value = false if (!inputName.value || !inputName.value.trim()) { @@ -240,6 +244,7 @@ const previewInner = () => { From 5f50ffd1ff46d9a9b035f57522fcf59970c4d1f1 Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Wed, 3 Sep 2025 00:15:01 +0800 Subject: [PATCH 4/4] refactor: Optimize the method of adding components so that they can be arranged in sequence --- .../src/views/dashboard/canvas/CanvasCore.vue | 45 +++++++++++++++++++ frontend/src/views/dashboard/editor/index.vue | 13 +++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/frontend/src/views/dashboard/canvas/CanvasCore.vue b/frontend/src/views/dashboard/canvas/CanvasCore.vue index 89f2acee1..d15450780 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 b82566253..34f7b248b 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