22
33import type {ChatMessage } from " @/api/chat.ts" ;
44import {computed , nextTick , ref } from " vue" ;
5- import type {TabsPaneContext } from ' element-plus-secondary'
65import {Loading } from " @element-plus/icons-vue" ;
7- import Component from " ./component/Component .vue"
6+ import ChartComponent from " ./component/ChartComponent .vue"
87import type {ChartTypes } from " @/views/chat/component/BaseChart.ts" ;
8+ import {ArrowDown } from " @element-plus/icons-vue" ;
9+ import ICON_BAR from " @/assets/svg/chart/bar.svg"
10+ import ICON_COLUMN from " @/assets/svg/chart/column.svg"
11+ import ICON_LINE from " @/assets/svg/chart/line.svg"
12+ import ICON_PIE from " @/assets/svg/chart/pie.svg"
13+ import ICON_TABLE from " @/assets/svg/chart/table.svg"
14+ import {find } from " lodash-es" ;
915
1016const props = defineProps <{
1117 message? : ChatMessage
@@ -29,10 +35,6 @@ const renderChartThinking = computed(() => {
2935 return props .message ?.record ?.chart_answer
3036})
3137
32- const handleClick = (tab : TabsPaneContext , event : Event ) => {
33- console .log (tab , event )
34- }
35-
3638const dataObject = computed <{
3739 fields: Array <string >,
3840 data: Array <{ [key : string ]: any }>,
@@ -92,10 +94,59 @@ const chartType = computed<ChartTypes>({
9294 }
9395})
9496
97+ function clickTab(type : " chart" | " sql" ) {
98+ settings .value .type = type
99+ }
100+
101+ const chartSelectRef = ref ()
102+
103+ function openChartSelect() {
104+ chartSelectRef .value .toggleMenu ()
105+ }
106+
107+ const chartTypeList = computed (() => {
108+ const _list = [{
109+ value: " table" ,
110+ icon: ICON_TABLE
111+ }]
112+ if (chartObject .value ) {
113+ switch (chartObject .value .type ) {
114+ case " table" :
115+ break
116+ case " column" :
117+ case " bar" :
118+ case " line" :
119+ _list .push ({
120+ value: " column" ,
121+ icon: ICON_COLUMN
122+ })
123+ _list .push ({
124+ value: " bar" ,
125+ icon: ICON_BAR
126+ })
127+ _list .push ({
128+ value: " line" ,
129+ icon: ICON_LINE
130+ })
131+ break
132+ case " pie" :
133+ _list .push ({
134+ value: " pie" ,
135+ icon: ICON_PIE
136+ })
137+ }
138+ }
139+
140+ return _list ;
141+ })
142+
143+ const currentChartTypeIcon = computed (() => {
144+ return find (chartTypeList .value , c => c .value === chartType .value )?.icon ?? ICON_TABLE
145+ })
146+
95147const chartRef = ref ()
96148
97- function onTypeChange(type : string ) {
98- console .log (type )
149+ function onTypeChange() {
99150 nextTick (() => {
100151 chartRef .value ?.destroyChart ()
101152 chartRef .value ?.renderChart ()
@@ -112,21 +163,36 @@ function onTypeChange(type: string) {
112163 <div v-if =" message.isTyping" >Thinking ...</div >
113164 <div v-if =" chartObject.title && !message.isTyping" >{{ chartObject.title }}</div >
114165 </div >
115- <el-tabs v-model =" settings.type" class =" type-tabs" @tab-click =" handleClick" tab-position =" top" >
116- <el-tab-pane label =" Chart" name =" chart" >
117- <template #label >
118- <el-select v-model =" chartType" style =" width : 80px " :disabled =" settings.type!== 'chart'"
119- @change =" onTypeChange" >
120- <el-option value =" table" >table</el-option >
121- <el-option value =" column" >column</el-option >
122- <el-option value =" bar" >bar</el-option >
123- <el-option value =" line" >line</el-option >
124- <el-option value =" pie" >pie</el-option >
125- </el-select >
126- </template >
127- </el-tab-pane >
128- <el-tab-pane label =" SQL" name =" sql" ></el-tab-pane >
129- </el-tabs >
166+ <div class =" tab-container" >
167+ <div class =" base-chart-choose-btn" @click =" clickTab('chart')" >
168+ <div class =" chart-choose-btn"
169+ :class =" {'active': settings.type === 'chart', 'no-click': settings.type !== 'chart'}"
170+ @click =" openChartSelect" >
171+ <el-icon size =" 34" >
172+ <component :is =" currentChartTypeIcon" />
173+ </el-icon >
174+ <el-icon >
175+ <ArrowDown />
176+ </el-icon >
177+ </div >
178+ <el-select v-model =" chartType" class =" inner-select" :disabled =" settings.type!== 'chart'"
179+ ref =" chartSelectRef"
180+ @change =" onTypeChange" >
181+ <el-option v-for =" t in chartTypeList " :key =" t.value" :value =" t.value" >
182+ <div class =" inner-chart-option" >
183+ <el-icon size =" 34" >
184+ <component :is =" t.icon" />
185+ </el-icon >
186+ {{ t.value }}
187+ </div >
188+ </el-option >
189+ </el-select >
190+
191+ </div >
192+ <div class =" chart-choose-btn" :class =" {'active': settings.type !== 'chart'}" @click =" clickTab('sql')" >
193+ SQL
194+ </div >
195+ </div >
130196 </el-header >
131197 <el-container direction =" vertical" >
132198 <template v-if =" message .record " >
@@ -163,7 +229,7 @@ function onTypeChange(type: string) {
163229 <div >
164230 <div v-if =" message.record.chart" class =" chart-base-container" >
165231 <div >
166- <Component
232+ <ChartComponent
167233 ref =" chartRef"
168234 v-if =" message.record.id"
169235 :id =" message.record.id"
@@ -205,4 +271,88 @@ function onTypeChange(type: string) {
205271 padding : 20px ;
206272 background : rgba (224 , 224 , 226 , 0.29 );
207273}
274+
275+ .tab-container {
276+ display : flex ;
277+ flex-direction : row ;
278+ align-items : center ;
279+ gap : 4px ;
280+ }
281+
282+ .base-chart-choose-btn {
283+ cursor : pointer ;
284+ color : var (--ed-color-primary );
285+ font-size : 16px ;
286+ font-weight : 500 ;
287+ height : 34px ;
288+
289+ border-radius : 4px ;
290+
291+ position : relative ;
292+
293+ & :hover {
294+ background : var (--ed-color-primary-light-5 );
295+ color : var (--ed-color-primary-light-9 );
296+ }
297+
298+ .inner-select {
299+
300+ position : absolute ;
301+
302+ :deep(.ed-select__wrapper ) {
303+ height : 0 ;
304+ padding : unset ;
305+ min-height : unset ;
306+ line-height : unset ;
307+ }
308+
309+ :deep(.ed-select__suffix ) {
310+ display : none ;
311+ }
312+
313+ :deep(.ed-select__selected-item ) {
314+ display : none ;
315+ }
316+
317+ }
318+
319+ }
320+
321+ .inner-chart-option {
322+ display : flex ;
323+ align-items : center ;
324+ flex-direction : row ;
325+ padding-right : 4px ;
326+ }
327+
328+ .chart-choose-btn {
329+
330+ cursor : pointer ;
331+ color : var (--ed-color-primary );
332+ font-size : 16px ;
333+ font-weight : 500 ;
334+ height : 34px ;
335+
336+ border-radius : 4px ;
337+
338+ display : flex ;
339+ flex-direction : row ;
340+ align-items : center ;
341+ justify-content : center ;
342+ padding : 0 4px ;
343+
344+ & .no-click {
345+ pointer-events : none ;
346+ }
347+
348+ & .active {
349+ background : var (--ed-color-primary-light-7 );
350+ color : var (--ed-color-primary );
351+ }
352+
353+ & :hover {
354+ background : var (--ed-color-primary-light-5 );
355+ color : var (--ed-color-primary-light-9 );
356+ }
357+ }
208358 </style >
0 commit comments