Skip to content

Commit 8fbc371

Browse files
committed
fix layout
fix layout
1 parent 33cd5d2 commit 8fbc371

File tree

11 files changed

+158
-72
lines changed

11 files changed

+158
-72
lines changed

frontend/src/components/Bubble.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const renderedContent = computed(() => {
2828
props.type === 'agent' && props.agentType === 'WriterAgent' ? 'bubble-writer' : '',
2929
props.class
3030
]">
31-
<div class="flex flex-col gap-1">
31+
<div class="flex flex-col gap-1 flex-1">
3232
<!-- 头像在上方 -->
3333
<span v-if="props.type === 'user'" class="text-2xl select-none mb-1">🧑</span>
3434
<span v-else-if="props.type === 'agent' && props.agentType === 'CoderAgent'"
@@ -105,10 +105,16 @@ const renderedContent = computed(() => {
105105
106106
.prose pre {
107107
@apply p-2 my-1 rounded bg-black/10 dark:bg-white/10 overflow-x-auto;
108+
max-width: 100%;
109+
width: 100%;
108110
}
109111
110112
.prose pre code {
111113
@apply bg-transparent p-0;
114+
@apply overflow-y-auto;
115+
max-width: 100%;
116+
white-space: pre-wrap;
117+
word-break: break-word;
112118
}
113119
114120
.prose blockquote {
@@ -151,6 +157,7 @@ const renderedContent = computed(() => {
151157
152158
.bubble {
153159
display: flex;
160+
flex: 1 1 0%;
154161
}
155162
156163
.bubble-user {

frontend/src/components/ChatArea.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const sendMessage = () => {
2323
</script>
2424

2525
<template>
26-
<div class="flex h-full flex-col p-4 bg-gray-50">
26+
<div class="flex h-full flex-col p-3 bg-gray-50">
2727
<div ref="scrollRef" class="flex-1 overflow-y-auto">
2828
<template v-for="message in props.messages" :key="message.id">
2929
<div class="mb-3">

frontend/src/components/CoderEditor.vue

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { ref } from 'vue'
33
import {
44
SidebarInset,
55
SidebarProvider,
6-
SidebarTrigger,
76
} from '@/components/ui/sidebar'
7+
import { ScrollArea } from '@/components/ui/scroll-area'
88
import Files from '@/components/Files.vue'
99
import NotebookArea from '@/components/NotebookArea.vue'
1010
import {
@@ -13,34 +13,36 @@ import {
1313
ResizableHandle,
1414
} from '@/components/ui/resizable'
1515
16-
const isCollapsed = ref(false)
17-
18-
// 处理折叠状态
19-
const handleCollapse = () => {
20-
isCollapsed.value = !isCollapsed.value
21-
}
22-
2316
</script>
2417
<template>
25-
<SidebarProvider :collapsed="isCollapsed">
26-
<ResizablePanelGroup direction="horizontal" class="h-full w-full min-w-0 min-h-0">
27-
<!-- 左侧 Files 面板 -->
28-
<ResizablePanel :default-size="20" :min-size="10" :max-size="40" class="h-full">
29-
<Files class="h-full border-r" />
30-
</ResizablePanel>
31-
<!-- 拖拽手柄 -->
32-
<ResizableHandle />
33-
<!-- 右侧 Notebook 面板 -->
34-
<ResizablePanel :default-size="80" :min-size="60" class="h-full">
35-
<SidebarInset class="flex-1 flex flex-col min-h-0 min-w-0 h-full">
36-
<header class="flex h-10 shrink-0 items-center gap-2 border-b px-4">
37-
<SidebarTrigger class="-ml-1" @click="handleCollapse" />
38-
</header>
39-
<div class="flex-1 min-h-0 min-w-0 overflow-auto h-full">
40-
<NotebookArea class="h-full min-w-0 pb-4" />
41-
</div>
42-
</SidebarInset>
43-
</ResizablePanel>
44-
</ResizablePanelGroup>
18+
<SidebarProvider>
19+
<SidebarInset class="flex-1 flex flex-col min-h-0 min-w-0 h-full">
20+
<div class="flex-1 min-h-0 min-w-0 overflow-auto h-full">
21+
<ResizablePanelGroup direction="horizontal" class="h-full w-full">
22+
<ResizablePanel :default-size="25" :min-size="15" class="h-full w-full flex flex-1">
23+
<ScrollArea class="h-full w-full flex flex-1">
24+
<Files class="h-full w-full fixed" />
25+
</ScrollArea>
26+
27+
</ResizablePanel>
28+
29+
<ResizableHandle with-handle />
30+
<ResizablePanel :default-size="75" :min-size="30" class="h-full w-full flex flex-1">
31+
<ScrollArea class="h-full w-full flex flex-1">
32+
<NotebookArea class="h-full min-w-0 pb-4" />
33+
</ScrollArea>
34+
</ResizablePanel>
35+
</ResizablePanelGroup>
36+
37+
</div>
38+
</SidebarInset>
4539
</SidebarProvider>
46-
</template>
40+
</template>
41+
42+
<style scoped>
43+
44+
::-webkit-scrollbar {
45+
display: none; /* 或者 width: 0; height: 0; */
46+
}
47+
48+
</style>

frontend/src/components/Files.vue

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
<script setup lang="ts">
2-
import { computed } from 'vue'
2+
import { computed, ref, onMounted } from 'vue'
33
import Tree from '@/components/Tree.vue'
4-
import {
5-
SidebarContent,
6-
SidebarGroup,
7-
SidebarGroupContent,
8-
SidebarGroupLabel,
9-
SidebarMenu,
10-
} from '@/components/ui/sidebar'
114
import { File } from 'lucide-vue-next'
125
import { useTaskStore } from '@/stores/task'
136
147
const taskStore = useTaskStore()
15-
8+
const isLoading = ref(true)
169
// 从消息中提取最新的文件列表
17-
const files = taskStore.files
10+
const files = taskStore.files as string[]
1811
1912
// 将文件列表转换为树形结构
2013
const fileTree = computed(() => {
21-
return files.map(file => file)
14+
// 无论files是否为空,只要计算属性被触发,就认为数据已加载完成
15+
isLoading.value = false
16+
17+
// 直接返回文件列表,不做转换,因为Tree组件期望接收string或数组
18+
return files
19+
})
20+
21+
// 添加超时机制,确保即使数据没有加载也会在一定时间后显示内容
22+
onMounted(() => {
23+
// 3秒后无论如何都取消加载状态
24+
setTimeout(() => {
25+
isLoading.value = false
26+
}, 3000)
2227
})
2328
2429
const handleFileClick = (file: string) => {
@@ -33,20 +38,20 @@ const handleFileDownload = (file: string) => {
3338
</script>
3439

3540
<template>
36-
<div class="h-full">
37-
<SidebarContent>
38-
<SidebarGroup>
39-
<SidebarGroupLabel>Files</SidebarGroupLabel>
40-
<SidebarGroupContent>
41-
<SidebarMenu>
42-
<div v-if="fileTree.length === 0" class="px-4 py-2 text-sm text-gray-500">
43-
No files
44-
</div>
45-
<Tree v-else v-for="(item, index) in fileTree" :key="index" :item="item" @click="handleFileClick(item)"
46-
@download="handleFileDownload(item)" />
47-
</SidebarMenu>
48-
</SidebarGroupContent>
49-
</SidebarGroup>
50-
</SidebarContent>
41+
<div class="h-full flex flex-col">
42+
<div class="px-3 py-2 font-medium text-sm border-b">Files</div>
43+
<div class="flex-1 overflow-auto">
44+
<div v-if="isLoading" class="px-3 py-2 text-sm text-gray-500">
45+
加载中...
46+
</div>
47+
<div v-else-if="fileTree.length === 0" class="px-3 py-2 text-sm text-gray-500">
48+
暂无文件
49+
</div>
50+
<div v-else class="p-2">
51+
<Tree v-for="(item, index) in fileTree" :key="index" :item="item"
52+
@click="handleFileClick(item)"
53+
@download="handleFileDownload(item)" />
54+
</div>
55+
</div>
5156
</div>
5257
</template>

frontend/src/components/NotebookArea.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const cells = computed<NoteCell[]>(() => {
4040
</script>
4141

4242
<template>
43-
<div class="flex-1 px-1 pt-1 pb-4 bg-gray-50 h-full overflow-y-auto">
43+
<div class="flex-1 px-1 pt-1 pb-4 h-full overflow-y-auto">
4444
<!-- 遍历所有单元格 -->
4545
<div v-for="(cell, index) in cells" :key="index"
4646
:class="[

frontend/src/components/WriterEditor.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ watch(() => props.messages, async (messages) => {
4242
</script>
4343

4444
<template>
45-
<div class="h-full overflow-hidden bg-gray-50">
45+
<div class="h-full overflow-hidden">
4646
<div class="h-full overflow-y-auto p-6">
4747
<div class="max-w-4xl mx-auto space-y-6">
4848
<TransitionGroup name="section" tag="div" class="space-y-6">
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script setup lang="ts">
2+
import { cn } from '@/lib/utils'
3+
import {
4+
ScrollAreaCorner,
5+
ScrollAreaRoot,
6+
type ScrollAreaRootProps,
7+
ScrollAreaViewport,
8+
} from 'reka-ui'
9+
import { computed, type HTMLAttributes } from 'vue'
10+
import ScrollBar from './ScrollBar.vue'
11+
12+
const props = defineProps<ScrollAreaRootProps & { class?: HTMLAttributes['class'] }>()
13+
14+
const delegatedProps = computed(() => {
15+
const { class: _, ...delegated } = props
16+
17+
return delegated
18+
})
19+
</script>
20+
21+
<template>
22+
<ScrollAreaRoot v-bind="delegatedProps" :class="cn('relative overflow-hidden', props.class)">
23+
<ScrollAreaViewport class="h-full w-full rounded-[inherit]">
24+
<slot />
25+
</ScrollAreaViewport>
26+
<ScrollBar />
27+
<ScrollAreaCorner />
28+
</ScrollAreaRoot>
29+
</template>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<script setup lang="ts">
2+
import { cn } from '@/lib/utils'
3+
import { ScrollAreaScrollbar, type ScrollAreaScrollbarProps, ScrollAreaThumb } from 'reka-ui'
4+
import { computed, type HTMLAttributes } from 'vue'
5+
6+
const props = withDefaults(defineProps<ScrollAreaScrollbarProps & { class?: HTMLAttributes['class'] }>(), {
7+
orientation: 'vertical',
8+
})
9+
10+
const delegatedProps = computed(() => {
11+
const { class: _, ...delegated } = props
12+
13+
return delegated
14+
})
15+
</script>
16+
17+
<template>
18+
<ScrollAreaScrollbar
19+
v-bind="delegatedProps"
20+
:class="
21+
cn('flex touch-none select-none transition-colors',
22+
orientation === 'vertical'
23+
&& 'h-full w-2.5 border-l border-l-transparent p-px',
24+
orientation === 'horizontal'
25+
&& 'h-2.5 flex-col border-t border-t-transparent p-px',
26+
props.class)"
27+
>
28+
<ScrollAreaThumb class="relative flex-1 rounded-full bg-border" />
29+
</ScrollAreaScrollbar>
30+
</template>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default as ScrollArea } from './ScrollArea.vue'
2+
export { default as ScrollBar } from './ScrollBar.vue'

frontend/src/pages/task/index.vue

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import WriterEditor from '@/components/WriterEditor.vue'
1919
import ChatArea from '@/components/ChatArea.vue'
2020
import { onMounted, onBeforeUnmount } from 'vue'
2121
import { useTaskStore } from '@/stores/task'
22-
22+
import { ScrollArea } from '@/components/ui/scroll-area'
2323
2424
const props = defineProps<{ task_id: string }>()
2525
const taskStore = useTaskStore()
@@ -37,15 +37,17 @@ onBeforeUnmount(() => {
3737
</script>
3838

3939
<template>
40-
<div class="fixed inset-0 overflow-hidden">
40+
<div class="fixed inset-0">
4141
<ResizablePanelGroup direction="horizontal" class="h-full rounded-lg border">
4242
<ResizablePanel :default-size="30" class="h-full">
43-
<ChatArea :messages="taskStore.chatMessages" />
43+
<ScrollArea class="h-full">
44+
<ChatArea :messages="taskStore.chatMessages" />
45+
</ScrollArea>
4446
</ResizablePanel>
4547
<ResizableHandle />
4648
<ResizablePanel :default-size="70" class="h-full min-w-0">
4749
<div class="flex h-full flex-col min-w-0">
48-
<Tabs default-value="coder" class="w-full h-full">
50+
<Tabs default-value="coder" class="w-full h-full flex flex-col">
4951
<div class="border-b px-4 py-1">
5052
<TabsList class="justify-center">
5153
<TabsTrigger value="coder" class="text-sm">
@@ -55,19 +57,20 @@ onBeforeUnmount(() => {
5557
WriterAgent
5658
</TabsTrigger>
5759
</TabsList>
60+
<!-- TODO: 其他选项 -->
5861
</div>
5962

60-
<TabsContent value="coder" class="flex-1 p-1 min-w-0 h-full overflow-hidden">
61-
<Card class="h-full min-w-0">
62-
<CardContent class="p-2 h-full min-w-0">
63-
<CoderEditor class="h-full min-w-0" />
63+
<TabsContent value="coder" class="h-full p-1 flex-1 overflow-auto">
64+
<Card class="h-full m-1">
65+
<CardContent class="h-full p-1">
66+
<CoderEditor />
6467
</CardContent>
6568
</Card>
6669
</TabsContent>
6770

68-
<TabsContent value="writer" class="flex-1 p-1 h-full overflow-hidden">
69-
<Card class="h-full">
70-
<CardContent class="p-2 h-full">
71+
<TabsContent value="writer" class="flex-1 p-1 min-w-0 h-full">
72+
<Card class="min-w-0 rounded-lg">
73+
<CardContent class="p-2 h-full min-w-0 overflow-hidden">
7174
<WriterEditor :messages="taskStore.writerMessages" />
7275
</CardContent>
7376
</Card>

0 commit comments

Comments
 (0)