From c068ae5780908d9183682e79ac5a759f2f46251f Mon Sep 17 00:00:00 2001
From: wangjiahao <1522128093@qq.com>
Date: Tue, 29 Jul 2025 11:20:06 +0800
Subject: [PATCH] refactor: support sq add view to dashboard
---
.../src/views/chat/chat-block/ChartBlock.vue | 7 +-
.../dashboard/common/AddViewDashboard.vue | 249 ++++++++++++++++++
.../dashboard/common/ResourceGroupOpt.vue | 4 -
.../dashboard/components/sq-view/index.vue | 1 -
.../src/views/dashboard/utils/canvasUtils.ts | 43 ++-
5 files changed, 291 insertions(+), 13 deletions(-)
create mode 100644 frontend/src/views/dashboard/common/AddViewDashboard.vue
diff --git a/frontend/src/views/chat/chat-block/ChartBlock.vue b/frontend/src/views/chat/chat-block/ChartBlock.vue
index 52e59969..96da119a 100644
--- a/frontend/src/views/chat/chat-block/ChartBlock.vue
+++ b/frontend/src/views/chat/chat-block/ChartBlock.vue
@@ -18,6 +18,7 @@ import icon_window_mini_outlined from '@/assets/svg/icon_window-mini_outlined.sv
import icon_copy_outlined from '@/assets/svg/icon_copy_outlined.svg'
import { useI18n } from 'vue-i18n'
import SQLComponent from '@/views/chat/component/SQLComponent.vue'
+import AddViewDashboard from '@/views/dashboard/common/AddViewDashboard.vue'
const props = withDefaults(
defineProps<{
@@ -34,7 +35,7 @@ const props = withDefaults(
)
const { t } = useI18n()
-
+const addViewRef = ref(null)
const emits = defineEmits(['exitFullScreen'])
const dataObject = computed<{
@@ -188,7 +189,8 @@ function showSql() {
}
function addToDashboard() {
- console.log('todo')
+ // @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ addViewRef.value?.optInit()
}
function copy() {
@@ -300,6 +302,7 @@ function copy() {
/>
+
+import { onMounted, reactive, ref } from 'vue'
+import {
+ findNextComponentIndex,
+ saveDashboardResourceTarget,
+} from '@/views/dashboard/utils/canvasUtils.ts'
+import { useI18n } from 'vue-i18n'
+import { dashboardApi } from '@/api/dashboard.ts'
+import type { SQTreeNode } from '@/views/dashboard/utils/treeNode.ts'
+import cloneDeep from 'lodash/cloneDeep'
+import { findNewComponentFromList } from '@/views/dashboard/components/component-list.ts'
+import { guid } from '@/utils/canvas.ts'
+
+const { t } = useI18n()
+const resource = ref(null)
+
+const optInit = (viewInfo: any) => {
+ resourceDialogShow.value = true
+ state.viewInfo = viewInfo
+}
+
+const state = reactive({
+ dashboardList: [] as SQTreeNode[],
+ viewInfo: null,
+})
+
+const resourceDialogShow = ref(false)
+const loading = ref(false)
+const resourceForm = reactive({
+ addType: 'history',
+ dashboardId: '',
+ dashboardName: '',
+})
+
+const resourceFormRulesNew = ref({
+ dashboardName: [
+ {
+ required: true,
+ min: 1,
+ max: 64,
+ message: t('dashboard.length_limit64'),
+ trigger: 'change',
+ },
+ ],
+})
+
+const resourceFormRulesHistory = ref({
+ dashboardId: [
+ {
+ required: true,
+ min: 1,
+ max: 64,
+ message: '请选择仪表板',
+ trigger: 'change',
+ },
+ ],
+})
+
+const resetForm = () => {
+ resourceForm.dashboardId = ''
+ resourceForm.dashboardName = ''
+ resourceDialogShow.value = false
+}
+
+const saveResourcePrepare = () => {
+ // @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ resource.value?.validate((result) => {
+ if (result) {
+ const component = cloneDeep(findNewComponentFromList('SQView'))
+ const newComponentId = guid()
+ if (resourceForm.addType === 'history' && component) {
+ findNextComponentIndex({ id: resourceForm.dashboardId }, (result: any) => {
+ const {
+ bottomPosition,
+ dashboardInfo,
+ canvasDataResult,
+ canvasStyleResult,
+ canvasViewInfoPreview,
+ } = result
+ const params = {
+ opt: 'updateLeaf',
+ pid: 'root',
+ id: resourceForm.dashboardId,
+ name: dashboardInfo.name,
+ }
+ component['id'] = newComponentId
+ component['y'] = bottomPosition + 1
+ canvasDataResult.push(component)
+ canvasViewInfoPreview[newComponentId] = state.viewInfo
+ const commonParams = {
+ componentData: canvasDataResult,
+ canvasStyleData: canvasStyleResult,
+ canvasViewInfo: canvasViewInfoPreview,
+ }
+ saveResource(params, commonParams)
+ })
+ } else if (resourceForm.addType === 'new' && component) {
+ const params = { opt: 'newLeaf', pid: 'root', name: resourceForm.dashboardName }
+ component['id'] = newComponentId
+ const commonParams = {
+ componentData: [component],
+ canvasStyleData: {},
+ canvasViewInfo: { newComponentId: state.viewInfo },
+ }
+ saveResource(params, commonParams)
+ }
+ }
+ })
+}
+
+const saveResource = (params: any, commonParams: any) => {
+ saveDashboardResourceTarget(params, commonParams, function () {
+ const messageTips = t('common.save_success')
+ ElMessage({
+ type: 'success',
+ message: messageTips,
+ })
+ resetForm()
+ })
+}
+
+const initDashboardList = () => {
+ state.dashboardList = []
+ const params = {}
+ dashboardApi.list_resource(params).then((res: SQTreeNode[]) => {
+ state.dashboardList = res || []
+ })
+}
+
+onMounted(() => {
+ initDashboardList()
+})
+
+defineExpose({
+ optInit,
+})
+
+
+
+
+
+
+
+ 存量仪表板
+ 新建仪表板
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('common.cancel') }}
+ {{ t('common.confirm') }}
+
+
+
+
+
diff --git a/frontend/src/views/dashboard/common/ResourceGroupOpt.vue b/frontend/src/views/dashboard/common/ResourceGroupOpt.vue
index f552b15e..bc1cdeeb 100644
--- a/frontend/src/views/dashboard/common/ResourceGroupOpt.vue
+++ b/frontend/src/views/dashboard/common/ResourceGroupOpt.vue
@@ -115,10 +115,6 @@ const propsTree = {
isLeaf: (node) => !node.children?.length,
}
-// const showPid = computed(() => {
-// return state.opt && ['newLeaf'].includes(state.opt) && state.parentSelect
-// })
-
const showPid = false
const saveResource = () => {
diff --git a/frontend/src/views/dashboard/components/sq-view/index.vue b/frontend/src/views/dashboard/components/sq-view/index.vue
index b2a11b49..ca25169b 100644
--- a/frontend/src/views/dashboard/components/sq-view/index.vue
+++ b/frontend/src/views/dashboard/components/sq-view/index.vue
@@ -2,7 +2,6 @@
import ChartComponent from '@/views/chat/component/ChartComponent.vue'
import icon_window_mini_outlined from '@/assets/svg/icon_window-mini_outlined.svg'
import SqViewDisplay from '@/views/dashboard/components/sq-view/index.vue'
-import _ from 'lodash'
const props = defineProps({
viewInfo: {
type: Object,
diff --git a/frontend/src/views/dashboard/utils/canvasUtils.ts b/frontend/src/views/dashboard/utils/canvasUtils.ts
index e7c50f52..99c502df 100644
--- a/frontend/src/views/dashboard/utils/canvasUtils.ts
+++ b/frontend/src/views/dashboard/utils/canvasUtils.ts
@@ -48,8 +48,39 @@ export const initCanvasData = (params: any, callBack: () => void) => {
})
}
+// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
+export const findNextComponentIndex = async (params: any, callBack: Function) => {
+ load_resource_prepare(params, function (result: any) {
+ let bottomPosition = 0
+ const { dashboardInfo, canvasDataResult, canvasStyleResult, canvasViewInfoPreview } = result
+ canvasDataResult.forEach((component: any) => {
+ const componentBottom = component.y + component.sizeY
+ if (componentBottom > bottomPosition) {
+ bottomPosition = componentBottom
+ }
+ })
+ callBack({
+ bottomPosition,
+ dashboardInfo,
+ canvasDataResult,
+ canvasStyleResult,
+ canvasViewInfoPreview,
+ })
+ })
+}
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
export const saveDashboardResource = (params: any, callBack: Function) => {
+ const commonParams = {
+ componentData: componentData.value,
+ canvasStyleData: canvasStyleData.value,
+ canvasViewInfo: canvasViewInfo.value,
+ }
+ saveDashboardResourceTarget(params, commonParams, callBack)
+}
+
+// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
+export const saveDashboardResourceTarget = (params: any, commonParams: any, callBack: Function) => {
params['workspace_id'] = workspace_id
dashboardApi.check_name(params).then((resCheck: any) => {
if (resCheck) {
@@ -57,9 +88,9 @@ export const saveDashboardResource = (params: any, callBack: Function) => {
// create canvas
const requestParams = {
...params,
- component_data: JSON.stringify(componentData.value),
- canvas_style_data: JSON.stringify(canvasStyleData.value),
- canvas_view_info: JSON.stringify(canvasViewInfo.value),
+ component_data: JSON.stringify(commonParams.componentData),
+ canvas_style_data: JSON.stringify(commonParams.canvasStyleData),
+ canvas_view_info: JSON.stringify(commonParams.canvasViewInfo),
}
dashboardApi.create_canvas(requestParams).then((res: any) => {
dashboardStore.updateDashboardInfo({
@@ -81,9 +112,9 @@ export const saveDashboardResource = (params: any, callBack: Function) => {
} else if (params.opt === 'updateLeaf') {
const requestParams = {
...params,
- component_data: JSON.stringify(componentData.value),
- canvas_style_data: JSON.stringify(canvasStyleData.value),
- canvas_view_info: JSON.stringify(canvasViewInfo.value),
+ component_data: JSON.stringify(commonParams.componentData),
+ canvas_style_data: JSON.stringify(commonParams.canvasStyleData),
+ canvas_view_info: JSON.stringify(commonParams.canvasViewInfo),
}
dashboardApi.update_canvas(requestParams).then(() => {
callBack()