| 1234567891011121314151617181920212223242526272829303132333435363738394041 |
- <script setup lang="ts">
- // 会话或工作组的文件列表:点击预览或分享
- import { onMounted, ref, watch } from 'vue'
- import type { FileDto } from '@agent-server/shared'
- import { fileIcon, formatSize, type FileClient } from '@agent-server/chat-ui'
- import { openFile } from '../lib/files'
- import { relativeTime } from '../lib/ui'
- const props = defineProps<{ client: FileClient; load: () => Promise<FileDto[]>; refreshKey?: unknown }>()
- const files = ref<FileDto[] | null>(null)
- const error = ref<string | null>(null)
- async function refresh() {
- try {
- files.value = (await props.load()).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))
- error.value = null
- } catch (err) {
- error.value = (err as Error).message
- }
- }
- onMounted(refresh)
- watch(() => props.refreshKey, refresh)
- </script>
- <template>
- <div class="m-list">
- <div v-if="error" class="px-4 py-3 text-error">{{ error }}</div>
- <div v-else-if="!files" class="px-4 py-3 text-fg-muted">加载中…</div>
- <div v-else-if="!files.length" class="px-4 py-3 text-fg-muted">还没有文件</div>
- <button
- v-for="f in files" v-else :key="f.id" type="button" class="m-row"
- @click="openFile(client, { fileId: f.id, path: f.path, mime: f.mime, size: f.size })"
- >
- <span class="codicon text-[18px] text-fg-muted" :class="fileIcon(f.mime, f.path)" />
- <span class="flex-1 min-w-0">
- <span class="block truncate">{{ f.path }}</span>
- <span class="block text-[12px] text-fg-muted">{{ formatSize(f.size) }} · {{ f.origin === 'upload' ? '上传' : '生成' }} · {{ relativeTime(f.updatedAt) }}</span>
- </span>
- </button>
- </div>
- </template>
|