Pr@main@refactor dashboard (#103)

* refactor: Optimize the logic for adding charts to the dashboard

* refactor: Support adding the modified chart with retained type to the dashboard

* refactor: Optimize dashboard name storage, enter key automatically saves

* refactor: Optimize the method of adding components so that they can be arranged in sequence
This commit is contained in:
王嘉豪
2025-09-03 08:20:30 +08:00
committed by GitHub
parent aaaa0c6c6e
commit a4dd431a5d
5 changed files with 70 additions and 11 deletions
@@ -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] : [],
@@ -395,7 +395,7 @@ watch(
</div>
</el-popover>
</div>
<div v-if="message?.record?.chart && !isAssistant">
<div v-if="message?.record?.chart && isCompletePage">
<el-tooltip effect="dark" :content="t('chat.add_to_dashboard')" placement="top">
<el-button class="tool-btn" text @click="addToDashboard">
<el-icon size="16">
@@ -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,
@@ -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,
})
}
@@ -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 = () => {
<input
ref="nameInput"
v-model="inputName"
@keydown.enter="handleEnterEditCanvasName"
@change="onDvNameChange"
@blur="closeEditCanvasName"
/>
+12 -1
View File
@@ -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