Skip to content

Commit c068ae5

Browse files
committed
refactor: support sq add view to dashboard
1 parent df4dc16 commit c068ae5

File tree

5 files changed

+291
-13
lines changed

5 files changed

+291
-13
lines changed

frontend/src/views/chat/chat-block/ChartBlock.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import icon_window_mini_outlined from '@/assets/svg/icon_window-mini_outlined.sv
1818
import icon_copy_outlined from '@/assets/svg/icon_copy_outlined.svg'
1919
import { useI18n } from 'vue-i18n'
2020
import SQLComponent from '@/views/chat/component/SQLComponent.vue'
21+
import AddViewDashboard from '@/views/dashboard/common/AddViewDashboard.vue'
2122
2223
const props = withDefaults(
2324
defineProps<{
@@ -34,7 +35,7 @@ const props = withDefaults(
3435
)
3536
3637
const { t } = useI18n()
37-
38+
const addViewRef = ref(null)
3839
const emits = defineEmits(['exitFullScreen'])
3940
4041
const dataObject = computed<{
@@ -188,7 +189,8 @@ function showSql() {
188189
}
189190
190191
function addToDashboard() {
191-
console.log('todo')
192+
// @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment
193+
addViewRef.value?.optInit()
192194
}
193195
194196
function copy() {
@@ -300,6 +302,7 @@ function copy() {
300302
/>
301303
</div>
302304

305+
<AddViewDashboard ref="addViewRef"></AddViewDashboard>
303306
<el-dialog
304307
v-if="!enlarge"
305308
v-model="dialogVisible"
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
<script lang="ts" setup>
2+
import { onMounted, reactive, ref } from 'vue'
3+
import {
4+
findNextComponentIndex,
5+
saveDashboardResourceTarget,
6+
} from '@/views/dashboard/utils/canvasUtils.ts'
7+
import { useI18n } from 'vue-i18n'
8+
import { dashboardApi } from '@/api/dashboard.ts'
9+
import type { SQTreeNode } from '@/views/dashboard/utils/treeNode.ts'
10+
import cloneDeep from 'lodash/cloneDeep'
11+
import { findNewComponentFromList } from '@/views/dashboard/components/component-list.ts'
12+
import { guid } from '@/utils/canvas.ts'
13+
14+
const { t } = useI18n()
15+
const resource = ref(null)
16+
17+
const optInit = (viewInfo: any) => {
18+
resourceDialogShow.value = true
19+
state.viewInfo = viewInfo
20+
}
21+
22+
const state = reactive({
23+
dashboardList: [] as SQTreeNode[],
24+
viewInfo: null,
25+
})
26+
27+
const resourceDialogShow = ref(false)
28+
const loading = ref(false)
29+
const resourceForm = reactive({
30+
addType: 'history',
31+
dashboardId: '',
32+
dashboardName: '',
33+
})
34+
35+
const resourceFormRulesNew = ref({
36+
dashboardName: [
37+
{
38+
required: true,
39+
min: 1,
40+
max: 64,
41+
message: t('dashboard.length_limit64'),
42+
trigger: 'change',
43+
},
44+
],
45+
})
46+
47+
const resourceFormRulesHistory = ref({
48+
dashboardId: [
49+
{
50+
required: true,
51+
min: 1,
52+
max: 64,
53+
message: '请选择仪表板',
54+
trigger: 'change',
55+
},
56+
],
57+
})
58+
59+
const resetForm = () => {
60+
resourceForm.dashboardId = ''
61+
resourceForm.dashboardName = ''
62+
resourceDialogShow.value = false
63+
}
64+
65+
const saveResourcePrepare = () => {
66+
// @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment
67+
resource.value?.validate((result) => {
68+
if (result) {
69+
const component = cloneDeep(findNewComponentFromList('SQView'))
70+
const newComponentId = guid()
71+
if (resourceForm.addType === 'history' && component) {
72+
findNextComponentIndex({ id: resourceForm.dashboardId }, (result: any) => {
73+
const {
74+
bottomPosition,
75+
dashboardInfo,
76+
canvasDataResult,
77+
canvasStyleResult,
78+
canvasViewInfoPreview,
79+
} = result
80+
const params = {
81+
opt: 'updateLeaf',
82+
pid: 'root',
83+
id: resourceForm.dashboardId,
84+
name: dashboardInfo.name,
85+
}
86+
component['id'] = newComponentId
87+
component['y'] = bottomPosition + 1
88+
canvasDataResult.push(component)
89+
canvasViewInfoPreview[newComponentId] = state.viewInfo
90+
const commonParams = {
91+
componentData: canvasDataResult,
92+
canvasStyleData: canvasStyleResult,
93+
canvasViewInfo: canvasViewInfoPreview,
94+
}
95+
saveResource(params, commonParams)
96+
})
97+
} else if (resourceForm.addType === 'new' && component) {
98+
const params = { opt: 'newLeaf', pid: 'root', name: resourceForm.dashboardName }
99+
component['id'] = newComponentId
100+
const commonParams = {
101+
componentData: [component],
102+
canvasStyleData: {},
103+
canvasViewInfo: { newComponentId: state.viewInfo },
104+
}
105+
saveResource(params, commonParams)
106+
}
107+
}
108+
})
109+
}
110+
111+
const saveResource = (params: any, commonParams: any) => {
112+
saveDashboardResourceTarget(params, commonParams, function () {
113+
const messageTips = t('common.save_success')
114+
ElMessage({
115+
type: 'success',
116+
message: messageTips,
117+
})
118+
resetForm()
119+
})
120+
}
121+
122+
const initDashboardList = () => {
123+
state.dashboardList = []
124+
const params = {}
125+
dashboardApi.list_resource(params).then((res: SQTreeNode[]) => {
126+
state.dashboardList = res || []
127+
})
128+
}
129+
130+
onMounted(() => {
131+
initDashboardList()
132+
})
133+
134+
defineExpose({
135+
optInit,
136+
})
137+
</script>
138+
139+
<template>
140+
<el-dialog
141+
v-model="resourceDialogShow"
142+
class="create-dialog"
143+
title="添加到仪表板"
144+
width="420px"
145+
:before-close="resetForm"
146+
append-to-body
147+
@submit.prevent
148+
>
149+
<el-form
150+
ref="resource"
151+
v-loading="loading"
152+
label-position="top"
153+
require-asterisk-position="right"
154+
:model="resourceForm"
155+
:rules="resourceForm.addType === 'new' ? resourceFormRulesNew : resourceFormRulesHistory"
156+
@submit.prevent
157+
>
158+
<el-form-item label="仪表板名称" required prop="addType">
159+
<el-radio-group v-model="resourceForm.addType">
160+
<el-radio value="history">存量仪表板</el-radio>
161+
<el-radio value="new">新建仪表板</el-radio>
162+
</el-radio-group>
163+
</el-form-item>
164+
<el-form-item
165+
v-if="resourceForm.addType === 'new'"
166+
label="仪表板"
167+
required
168+
prop="dashboardName"
169+
>
170+
<el-input
171+
v-model="resourceForm.dashboardName"
172+
clearable
173+
placeholder="请输入仪表板名称"
174+
@keydown.stop
175+
@keyup.stop
176+
/>
177+
</el-form-item>
178+
<el-form-item
179+
v-if="resourceForm.addType === 'history'"
180+
label="仪表板"
181+
required
182+
prop="dashboardId"
183+
>
184+
<el-select v-model="resourceForm.dashboardId" placeholder="请选择仪表板">
185+
<el-option
186+
v-for="item in state.dashboardList"
187+
:key="item.id"
188+
:label="item.name"
189+
:value="item.id"
190+
/>
191+
</el-select>
192+
</el-form-item>
193+
</el-form>
194+
<template #footer>
195+
<el-button secondary @click="resetForm()">{{ t('common.cancel') }}</el-button>
196+
<el-button type="primary" @click="saveResourcePrepare()">{{ t('common.confirm') }}</el-button>
197+
</template>
198+
</el-dialog>
199+
</template>
200+
201+
<style lang="less" scoped>
202+
.tree-content {
203+
width: 552px;
204+
height: 380px;
205+
border: 1px solid #dee0e3;
206+
border-radius: 4px;
207+
padding: 8px;
208+
overflow-y: auto;
209+
210+
.empty-search {
211+
width: 100%;
212+
margin-top: 57px;
213+
display: flex;
214+
flex-direction: column;
215+
align-items: center;
216+
217+
img {
218+
width: 100px;
219+
height: 100px;
220+
margin-bottom: 8px;
221+
}
222+
223+
span {
224+
font-family: var(--de-custom_font, 'PingFang');
225+
font-size: 14px;
226+
font-weight: 400;
227+
line-height: 22px;
228+
color: #646a73;
229+
}
230+
}
231+
}
232+
233+
.custom-tree-node {
234+
display: flex;
235+
align-items: center;
236+
237+
span {
238+
margin-left: 8.75px;
239+
width: 120px;
240+
white-space: nowrap;
241+
text-overflow: ellipsis;
242+
overflow: hidden;
243+
}
244+
}
245+
246+
.custom-tree-folder {
247+
color: rgb(255, 198, 10);
248+
}
249+
</style>

frontend/src/views/dashboard/common/ResourceGroupOpt.vue

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,6 @@ const propsTree = {
115115
isLeaf: (node) => !node.children?.length,
116116
}
117117
118-
// const showPid = computed(() => {
119-
// return state.opt && ['newLeaf'].includes(state.opt) && state.parentSelect
120-
// })
121-
122118
const showPid = false
123119
124120
const saveResource = () => {

frontend/src/views/dashboard/components/sq-view/index.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import ChartComponent from '@/views/chat/component/ChartComponent.vue'
33
import icon_window_mini_outlined from '@/assets/svg/icon_window-mini_outlined.svg'
44
import SqViewDisplay from '@/views/dashboard/components/sq-view/index.vue'
5-
import _ from 'lodash'
65
const props = defineProps({
76
viewInfo: {
87
type: Object,

frontend/src/views/dashboard/utils/canvasUtils.ts

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,49 @@ export const initCanvasData = (params: any, callBack: () => void) => {
4848
})
4949
}
5050

51+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
52+
export const findNextComponentIndex = async (params: any, callBack: Function) => {
53+
load_resource_prepare(params, function (result: any) {
54+
let bottomPosition = 0
55+
const { dashboardInfo, canvasDataResult, canvasStyleResult, canvasViewInfoPreview } = result
56+
canvasDataResult.forEach((component: any) => {
57+
const componentBottom = component.y + component.sizeY
58+
if (componentBottom > bottomPosition) {
59+
bottomPosition = componentBottom
60+
}
61+
})
62+
callBack({
63+
bottomPosition,
64+
dashboardInfo,
65+
canvasDataResult,
66+
canvasStyleResult,
67+
canvasViewInfoPreview,
68+
})
69+
})
70+
}
71+
5172
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
5273
export const saveDashboardResource = (params: any, callBack: Function) => {
74+
const commonParams = {
75+
componentData: componentData.value,
76+
canvasStyleData: canvasStyleData.value,
77+
canvasViewInfo: canvasViewInfo.value,
78+
}
79+
saveDashboardResourceTarget(params, commonParams, callBack)
80+
}
81+
82+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
83+
export const saveDashboardResourceTarget = (params: any, commonParams: any, callBack: Function) => {
5384
params['workspace_id'] = workspace_id
5485
dashboardApi.check_name(params).then((resCheck: any) => {
5586
if (resCheck) {
5687
if (params.opt === 'newLeaf') {
5788
// create canvas
5889
const requestParams = {
5990
...params,
60-
component_data: JSON.stringify(componentData.value),
61-
canvas_style_data: JSON.stringify(canvasStyleData.value),
62-
canvas_view_info: JSON.stringify(canvasViewInfo.value),
91+
component_data: JSON.stringify(commonParams.componentData),
92+
canvas_style_data: JSON.stringify(commonParams.canvasStyleData),
93+
canvas_view_info: JSON.stringify(commonParams.canvasViewInfo),
6394
}
6495
dashboardApi.create_canvas(requestParams).then((res: any) => {
6596
dashboardStore.updateDashboardInfo({
@@ -81,9 +112,9 @@ export const saveDashboardResource = (params: any, callBack: Function) => {
81112
} else if (params.opt === 'updateLeaf') {
82113
const requestParams = {
83114
...params,
84-
component_data: JSON.stringify(componentData.value),
85-
canvas_style_data: JSON.stringify(canvasStyleData.value),
86-
canvas_view_info: JSON.stringify(canvasViewInfo.value),
115+
component_data: JSON.stringify(commonParams.componentData),
116+
canvas_style_data: JSON.stringify(commonParams.canvasStyleData),
117+
canvas_view_info: JSON.stringify(commonParams.canvasViewInfo),
87118
}
88119
dashboardApi.update_canvas(requestParams).then(() => {
89120
callBack()

0 commit comments

Comments
 (0)