refactor: dashboard view select

This commit is contained in:
wangjiahao
2025-06-13 16:56:41 +08:00
parent dea866c07b
commit 5f2ba0a985
4 changed files with 270 additions and 13 deletions
@@ -50,18 +50,12 @@ const props = defineProps({
type: Boolean,
default: false,
},
showPosition: {
type: String,
required: false,
default: 'preview',
},
})
const { configItem, showPosition } = toRefs(props)
const tinymceId = 'tinymce-view-' + configItem.value.id + '-' + showPosition.value
const { configItem } = toRefs(props)
const tinymceId = 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
const init = reactive({
selector: tinymceId,
toolbar_items_size: 'small',
language_url: '/tinymce-sqlbot-private/langs/zh_CN.js',
language: 'zh_CN',
skin_url: '/tinymce-sqlbot-private/skins/ui/oxide',
@@ -92,6 +86,12 @@ const isDisabled = computed(() => props.disabled || !configItem.value.editing)
const setEdit = () => {
configItem.value.editing = true
// @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment
const ed = tinymce.editors[tinymceId]
ed.setContent(configItem.value.propValue)
nextTick(() => {
editCursor()
})
}
const editCursor = () => {
@@ -1,7 +1,42 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import ChartComponent from '@/views/chat/component/ChartComponent.vue'
import { reactive } from 'vue'
import type { ChartAxis, ChartData } from '@/views/chat/component/BaseChart.ts'
const state = reactive({
chartInfo: {
id: null as string | null,
type: '' as string,
columns: [] as ChartAxis[],
xAxis: [] as ChartAxis[],
yAxis: [] as ChartAxis[],
series: [] as ChartAxis[],
data: [] as ChartData[],
},
})
</script>
<template>
<div></div>
<div class="chart-base-container">
<div>
<ChartComponent
v-if="state.chartInfo.id"
:id="state.chartInfo.id"
ref="chartRef"
:type="state.chartInfo.type"
:columns="state.chartInfo.columns"
:x="state.chartInfo.xAxis"
:y="state.chartInfo.yAxis"
:series="state.chartInfo.series"
:data="state.chartInfo.data"
/>
</div>
</div>
</template>
<style scoped lang="less"></style>
<style scoped lang="less">
.chart-base-container {
padding: 20px;
background: rgba(224, 224, 226, 0.29);
}
</style>
@@ -8,7 +8,25 @@
modal-class="custom-drawer"
@closed="handleClose()"
>
<div>Preview</div>
<el-container class="chat-container">
<el-aside class="chat-container-left">
<el-container class="chat-container-right-container">
<el-main class="chat-list">
<DashboardChatList
v-model:loading="loading"
:current-chat-id="currentChatId"
:chat-list="chatList"
@chat-selected="onClickHistory"
/>
</el-main>
</el-container>
</el-aside>
<el-container :loading="loading">
<el-main class="chat-record-list">
<el-scrollbar ref="chatListRef"> </el-scrollbar>
</el-main>
</el-container>
</el-container>
<template #footer>
<el-row class="multiplexing-footer">
@@ -31,14 +49,58 @@
</template>
<script setup lang="ts">
import { computed, reactive, ref } from 'vue'
import { computed, onMounted, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { Chat, chatApi, ChatInfo } from '@/api/chat.ts'
import DashboardChatList from '@/views/dashboard/editor/DashboardChatList.vue'
const dialogShow = ref(false)
const { t } = useI18n()
const selectComponentCount = computed(() => Object.keys(state.curMultiplexingComponents).length)
const state = reactive({
curMultiplexingComponents: {},
})
const loading = ref<boolean>(false)
const chatList = ref<Array<ChatInfo>>([])
const currentChatId = ref<number | undefined>()
const currentChat = ref<ChatInfo>(new ChatInfo())
onMounted(() => {
getChatList()
})
function onClickHistory(chat: Chat) {
currentChat.value = new ChatInfo(chat)
if (chat !== undefined && chat.id !== undefined && !loading.value) {
currentChatId.value = chat.id
loading.value = true
chatApi
.get(chat.id)
.then((res) => {
const info = chatApi.toChatInfo(res)
if (info) {
currentChat.value = info
}
})
.finally(() => {
loading.value = false
})
}
}
function getChatList() {
loading.value = true
chatApi
.list()
.then((res) => {
chatList.value = chatApi.toChatInfoList(res)
})
.finally(() => {
loading.value = false
})
}
const dialogInit = () => {
dialogShow.value = true
state.curMultiplexingComponents = {}
@@ -107,4 +169,69 @@ defineExpose({
padding: 0 0 64px 0 !important;
}
}
.chat-container {
height: 100%;
.chat-container-left {
padding-top: 20px;
--ed-aside-width: 260px;
box-shadow: 0 0 3px #d7d7d7;
z-index: 1;
background: var(--ed-fill-color-blank);
.chat-container-right-container {
height: 100%;
.chat-list-header {
display: flex;
align-items: center;
justify-content: center;
}
.chat-list {
padding: 0 0 20px 0;
}
}
}
.chat-record-list {
padding: 0 0 20px 0;
}
.chat-footer {
--ed-footer-height: 120px;
display: flex;
flex-direction: column;
.input-wrapper {
flex: 1;
position: relative;
.input-area {
height: 100%;
padding-bottom: 8px;
:deep(.ed-textarea__inner) {
height: 100% !important;
}
}
.input-icon {
min-width: unset;
position: absolute;
bottom: 14px;
right: 8px;
}
}
}
.send-btn {
min-width: 0;
}
}
</style>
@@ -0,0 +1,95 @@
<script setup lang="ts">
import { type Chat } from '@/api/chat.ts'
withDefaults(
defineProps<{
currentChatId?: number
chatList: Array<Chat>
}>(),
{
currentChatId: undefined,
chatList: () => [],
}
)
const emits = defineEmits(['chatSelected'])
function onClickHistory(chat: Chat) {
emits('chatSelected', chat)
}
</script>
<template>
<el-scrollbar ref="chatListRef">
<div class="chat-list-inner">
<template v-for="chat in chatList" :key="chat.id">
<div
class="chat-list-item"
:class="{ active: currentChatId === chat.id }"
@click="onClickHistory(chat)"
>
<span class="title">{{ chat.brief ?? 'Untitled' }}</span>
</div>
</template>
</div>
</el-scrollbar>
</template>
<style scoped lang="less">
.chat-list-inner {
--hover-color: var(--ed-color-primary-light-9);
--active-color: var(--hover-color);
padding-left: 14px;
padding-right: 14px;
width: 100%;
display: flex;
flex-direction: column;
gap: 8px;
.chat-list-item {
width: 100%;
height: 42px;
cursor: pointer;
border-radius: 6px;
line-height: 1em;
display: flex;
align-items: center;
padding: 8px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
.title {
flex: 1;
width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.icon-more {
margin-left: auto;
display: none;
min-width: unset;
}
&:hover {
background-color: var(--hover-color);
.icon-more {
display: inline-flex;
}
}
&.active {
background-color: var(--active-color);
}
}
}
</style>