frontend 兼容
This commit is contained in:
103
ai-chat-web/src/views/chat/layout/SiderRight/List.vue
Normal file
103
ai-chat-web/src/views/chat/layout/SiderRight/List.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<script setup lang='ts'>
|
||||
import { computed } from 'vue'
|
||||
import { NInput, NPopconfirm, NScrollbar } from 'naive-ui'
|
||||
import { SvgIcon } from '@/components/common'
|
||||
import { useAppStore, useChatStore } from '@/store'
|
||||
import { useBasicLayout } from '@/hooks/useBasicLayout'
|
||||
|
||||
const { isMobile } = useBasicLayout()
|
||||
|
||||
const appStore = useAppStore()
|
||||
const chatStore = useChatStore()
|
||||
|
||||
const dataSources = computed(() => chatStore.history)
|
||||
|
||||
async function handleSelect({ uuid }: Chat.History) {
|
||||
if (isActive(uuid))
|
||||
return
|
||||
|
||||
if (chatStore.active)
|
||||
chatStore.updateHistory(chatStore.active, { isEdit: false })
|
||||
await chatStore.setActive(uuid)
|
||||
|
||||
if (isMobile.value)
|
||||
appStore.setSiderCollapsed(true)
|
||||
}
|
||||
|
||||
function handleEdit({ uuid }: Chat.History, isEdit: boolean, event?: MouseEvent) {
|
||||
event?.stopPropagation()
|
||||
chatStore.updateHistory(uuid, { isEdit })
|
||||
}
|
||||
|
||||
function handleDelete(index: number, event?: MouseEvent | TouchEvent) {
|
||||
event?.stopPropagation()
|
||||
chatStore.deleteHistory(index)
|
||||
if (isMobile.value)
|
||||
appStore.setSiderCollapsed(true)
|
||||
}
|
||||
|
||||
function handleEnter({ uuid }: Chat.History, isEdit: boolean, event: KeyboardEvent) {
|
||||
event?.stopPropagation()
|
||||
if (event.key === 'Enter')
|
||||
chatStore.updateHistory(uuid, { isEdit })
|
||||
}
|
||||
|
||||
function isActive(uuid: number) {
|
||||
return chatStore.active === uuid
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NScrollbar class="px-4">
|
||||
<div class="flex flex-col gap-2 text-sm">
|
||||
<template v-if="!dataSources.length">
|
||||
<div class="flex flex-col items-center mt-4 text-center text-neutral-300">
|
||||
<SvgIcon icon="ri:inbox-line" class="mb-2 text-3xl" />
|
||||
<span>{{ $t('common.noData') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div v-for="(item, index) of dataSources" :key="index">
|
||||
<a
|
||||
class="relative flex items-center gap-3 px-3 py-3 break-all border rounded-md cursor-pointer hover:bg-neutral-100 group dark:border-neutral-800 dark:hover:bg-[#24272e]"
|
||||
:class="isActive(item.uuid) && ['border-[#4b9e5f]', 'bg-neutral-100', 'text-[#4b9e5f]', 'dark:bg-[#24272e]', 'dark:border-[#4b9e5f]', 'pr-14']"
|
||||
@click="handleSelect(item)"
|
||||
>
|
||||
<span>
|
||||
<SvgIcon icon="ri:message-3-line" />
|
||||
</span>
|
||||
<div class="relative flex-1 overflow-hidden break-all text-ellipsis whitespace-nowrap">
|
||||
<NInput
|
||||
v-if="item.isEdit"
|
||||
v-model:value="item.title"
|
||||
size="tiny"
|
||||
@keypress="handleEnter(item, false, $event)"
|
||||
/>
|
||||
<span v-else>{{ item.title }}</span>
|
||||
</div>
|
||||
<div v-if="isActive(item.uuid)" class="absolute z-10 flex visible right-1">
|
||||
<template v-if="item.isEdit">
|
||||
<button class="p-1" @click="handleEdit(item, false, $event)">
|
||||
<SvgIcon icon="ri:save-line" />
|
||||
</button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<button class="p-1">
|
||||
<SvgIcon icon="ri:edit-line" @click="handleEdit(item, true, $event)" />
|
||||
</button>
|
||||
<NPopconfirm placement="bottom" @positive-click="handleDelete(index, $event)">
|
||||
<template #trigger>
|
||||
<button class="p-1">
|
||||
<SvgIcon icon="ri:delete-bin-line" />
|
||||
</button>
|
||||
</template>
|
||||
{{ $t('chat.deleteHistoryConfirm') }}
|
||||
</NPopconfirm>
|
||||
</template>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</NScrollbar>
|
||||
</template>
|
||||
Reference in New Issue
Block a user