Add File
This commit is contained in:
234
frontend/src/views/dashboard/editor/DashboardChatList.vue
Normal file
234
frontend/src/views/dashboard/editor/DashboardChatList.vue
Normal file
@@ -0,0 +1,234 @@
|
||||
<script setup lang="ts">
|
||||
import { type Chat } from '@/api/chat.ts'
|
||||
import { ElIcon } from 'element-plus-secondary'
|
||||
import { Icon } from '@/components/icon-custom'
|
||||
import { ref, computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlined.svg'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
currentChatId?: number
|
||||
chatList: Array<Chat>
|
||||
}>(),
|
||||
{
|
||||
currentChatId: undefined,
|
||||
chatList: () => [],
|
||||
}
|
||||
)
|
||||
const { t } = useI18n()
|
||||
const emits = defineEmits(['chatSelected'])
|
||||
const filterText = ref('')
|
||||
|
||||
function onClickHistory(chat: Chat) {
|
||||
emits('chatSelected', chat)
|
||||
}
|
||||
|
||||
const now = new Date()
|
||||
const startOfWeek = new Date(now)
|
||||
startOfWeek.setDate(now.getDate() - now.getDay() + (now.getDay() === 0 ? -6 : 1)) // 设置为本周一
|
||||
startOfWeek.setHours(0, 0, 0, 0)
|
||||
|
||||
const filteredAndGroupedData = computed(() => {
|
||||
const today: Chat[] = []
|
||||
const thisWeek: Chat[] = []
|
||||
const earlier: Chat[] = []
|
||||
|
||||
const filteredList = props.chatList.filter(
|
||||
(chat) =>
|
||||
!filterText.value ||
|
||||
(chat.brief && chat.brief.toLowerCase().includes(filterText.value.toLowerCase()))
|
||||
)
|
||||
|
||||
filteredList.forEach((item) => {
|
||||
// @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
const itemDate = new Date(item.create_time)
|
||||
|
||||
if (
|
||||
itemDate.getDate() === now.getDate() &&
|
||||
itemDate.getMonth() === now.getMonth() &&
|
||||
itemDate.getFullYear() === now.getFullYear()
|
||||
) {
|
||||
today.push(item)
|
||||
} else if (itemDate >= startOfWeek && itemDate < now) {
|
||||
thisWeek.push(item)
|
||||
} else {
|
||||
earlier.push(item)
|
||||
}
|
||||
})
|
||||
|
||||
return { today, thisWeek, earlier }
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div style="width: 100%; height: 100%">
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
:placeholder="t('dashboard.search')"
|
||||
clearable
|
||||
class="search-bar"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon>
|
||||
<Icon name="icon_search-outline_outlined">
|
||||
<icon_searchOutline_outlined class="svg-icon" />
|
||||
</Icon>
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-scrollbar ref="chatListRef" class="custom-chart-list">
|
||||
<div class="chat-list-inner">
|
||||
<!-- today -->
|
||||
<div v-if="filteredAndGroupedData.today.length > 0" class="time-group">
|
||||
<div class="time-group-title">{{ t('dashboard.today') }}</div>
|
||||
<div
|
||||
v-for="chat in filteredAndGroupedData.today"
|
||||
:key="chat.id"
|
||||
class="chat-list-item"
|
||||
:class="{ active: currentChatId === chat.id }"
|
||||
@click="onClickHistory(chat)"
|
||||
>
|
||||
<span class="title">{{ chat.brief ?? 'Untitled' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- this week -->
|
||||
<div v-if="filteredAndGroupedData.thisWeek.length > 0" class="time-group">
|
||||
<div class="time-group-title">{{ t('dashboard.this_week') }}</div>
|
||||
<div
|
||||
v-for="chat in filteredAndGroupedData.thisWeek"
|
||||
:key="chat.id"
|
||||
class="chat-list-item"
|
||||
:class="{ active: currentChatId === chat.id }"
|
||||
@click="onClickHistory(chat)"
|
||||
>
|
||||
<span class="title">{{ chat.brief ?? 'Untitled' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- earlier -->
|
||||
<div v-if="filteredAndGroupedData.earlier.length > 0" class="time-group">
|
||||
<div class="time-group-title">{{ t('dashboard.earlier') }}</div>
|
||||
<div
|
||||
v-for="chat in filteredAndGroupedData.earlier"
|
||||
:key="chat.id"
|
||||
class="chat-list-item"
|
||||
:class="{ active: currentChatId === chat.id }"
|
||||
@click="onClickHistory(chat)"
|
||||
>
|
||||
<span class="title">{{ chat.brief ?? 'Untitled' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- no data -->
|
||||
<div
|
||||
v-if="
|
||||
filteredAndGroupedData.today.length === 0 &&
|
||||
filteredAndGroupedData.thisWeek.length === 0 &&
|
||||
filteredAndGroupedData.earlier.length === 0
|
||||
"
|
||||
class="no-data"
|
||||
>
|
||||
{{ t('dashboard.no_data') }}
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</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;
|
||||
|
||||
.time-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-top: 12px;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.time-group-title {
|
||||
font-size: 12px;
|
||||
color: rgba(100, 106, 115, 1);
|
||||
padding: 4px 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-list-item {
|
||||
width: 100%;
|
||||
height: 42px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
line-height: 1em;
|
||||
margin-bottom: 2px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px;
|
||||
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
.title {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
color: rgba(31, 35, 41, 1);
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.icon-more {
|
||||
margin-left: auto;
|
||||
display: none;
|
||||
|
||||
min-width: unset;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.75);
|
||||
|
||||
.icon-more {
|
||||
display: inline-flex;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.no-data {
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
margin-top: 140px;
|
||||
color: var(--ed-text-color-placeholder);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
.custom-chart-list {
|
||||
height: calc(100% - 32px);
|
||||
}
|
||||
.search-bar {
|
||||
padding: 0 12px 10px 12px;
|
||||
width: 100%;
|
||||
--ed-input-bg-color: rgba(245, 246, 247, 1);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user