feat(web): 统一交付物和文件树的预览逻辑
This commit is contained in:
parent
0d1e26cf7b
commit
824270a035
@ -59,7 +59,7 @@
|
||||
|
||||
- 优化 Agent 输入框 mention 行为:在保留附件 mention 的同时,将共享 `workspace` 文件纳入候选范围;并将 `@` 空查询时的候选列表改为空,仅在继续输入后再执行筛选,避免工作区文件过多时直接铺满下拉面板
|
||||
- 为前端工作台文件树补齐文件删除能力:`/api/viewer/filesystem/file` 新增删除接口,`AgentPanel` 文件节点新增删除按钮与确认交互,删除后会同步刷新树与预览状态
|
||||
- 调整前端工作台文件预览交互:恢复默认侧边/弹窗预览,并新增显式“全屏预览”入口;全屏模式下由预览内容直接覆盖整页,仅保留右上角悬浮关闭按钮;
|
||||
- 调整前端工作台文件预览交互:恢复默认侧边/弹窗预览,并新增显式“全屏预览”入口;全屏模式下由预览内容直接覆盖整页,仅保留右上角悬浮关闭按钮;同时修复 HTML 文件首次在弹窗中预览偶现白屏的问题,改为在内容更新后强制重建 `iframe`
|
||||
- 统一 Agent Panel 文件预览与消息区交付物预览组件:两处改为复用同一套 `AgentFilePreview` 预览实现,并为交付物预览补齐与工作台一致的“全屏预览”入口
|
||||
- 兼容旧版已安装的内置 `reporter` 技能记录:`update_builtin_skill` 现在会识别由 `system` 或 `builtin-system` 管理的历史记录,避免更新时误报“技能 `reporter` 不是内置 skill”
|
||||
- 调整沙盒 user-data 目录隔离策略:`workspace` 改为共享目录 `saves/threads/shared/workspace`,`uploads/outputs` 继续保持 thread 级隔离;同时更新 thread artifact 权限校验、viewer 文件系统列举逻辑,以及对应的 router/E2E 测试
|
||||
|
||||
@ -51,6 +51,7 @@
|
||||
:bodyStyle="{ maxHeight: '90vh', overflow: 'auto' }"
|
||||
:footer="null"
|
||||
:closable="false"
|
||||
wrapClassName="agent-file-preview-modal"
|
||||
@cancel="closePreview"
|
||||
>
|
||||
<AgentFilePreview
|
||||
|
||||
@ -60,10 +60,11 @@
|
||||
</template>
|
||||
<template v-else-if="isHtmlFile && htmlPreviewMode === 'render'">
|
||||
<iframe
|
||||
:key="`embedded-${htmlPreviewRenderKey}`"
|
||||
class="html-preview"
|
||||
:srcdoc="formatContent(file?.content)"
|
||||
:title="filePath"
|
||||
sandbox=""
|
||||
sandbox="allow-scripts"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="isMarkdown">
|
||||
@ -143,10 +144,11 @@
|
||||
</template>
|
||||
<template v-else-if="isHtmlFile && htmlPreviewMode === 'render'">
|
||||
<iframe
|
||||
:key="`fullscreen-${htmlPreviewRenderKey}`"
|
||||
class="html-preview fullscreen-embed-preview"
|
||||
:srcdoc="formatContent(file?.content)"
|
||||
:title="filePath"
|
||||
sandbox=""
|
||||
sandbox="allow-scripts"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="isMarkdown">
|
||||
@ -237,6 +239,7 @@ const themeStore = useThemeStore()
|
||||
const theme = computed(() => (themeStore.isDark ? 'dark' : 'light'))
|
||||
const htmlPreviewMode = ref('render')
|
||||
const fullscreenPreviewVisible = ref(false)
|
||||
const htmlPreviewRenderKey = ref(0)
|
||||
|
||||
const isMarkdown = computed(() => isMarkdownPreview(props.filePath, props.file?.previewType))
|
||||
const isHtmlFile = computed(
|
||||
@ -302,6 +305,15 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
[() => props.filePath, () => props.file?.previewType, () => props.file?.content],
|
||||
() => {
|
||||
if (isHtmlFile.value) {
|
||||
htmlPreviewRenderKey.value += 1
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
watch(fullscreenPreviewVisible, (visible) => {
|
||||
document.body.style.overflow = visible ? 'hidden' : ''
|
||||
})
|
||||
@ -314,6 +326,8 @@ onUnmounted(() => {
|
||||
<style scoped lang="less">
|
||||
.agent-file-preview {
|
||||
min-width: 0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.agent-file-preview.is-full-height {
|
||||
@ -396,7 +410,7 @@ onUnmounted(() => {
|
||||
min-height: 300px;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
border-radius: 6px;
|
||||
border-radius: 0px;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
@ -431,12 +445,12 @@ onUnmounted(() => {
|
||||
word-wrap: break-word;
|
||||
color: var(--gray-1000);
|
||||
background: transparent;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.file-content-pre.code-highlight {
|
||||
border-radius: 8px;
|
||||
background: var(--gray-25);
|
||||
border: 1px solid var(--gray-150);
|
||||
white-space: pre;
|
||||
overflow-x: auto;
|
||||
}
|
||||
@ -474,9 +488,9 @@ onUnmounted(() => {
|
||||
.html-preview {
|
||||
width: 100%;
|
||||
min-height: calc(80vh - 40px);
|
||||
border: 1px solid var(--gray-150);
|
||||
border-radius: 6px;
|
||||
background: #fff;
|
||||
border: none;
|
||||
border-radius: 0px;
|
||||
background: #fff; // HTML 内容通常需要白色背景以保证可读性
|
||||
}
|
||||
|
||||
.unsupported-preview {
|
||||
@ -516,7 +530,7 @@ onUnmounted(() => {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
background: var(--color-trans-light);
|
||||
border: 1px solid var(--gray-200);
|
||||
box-shadow: 0 10px 30px rgba(15, 23, 42, 0.14);
|
||||
backdrop-filter: blur(10px);
|
||||
@ -532,7 +546,7 @@ onUnmounted(() => {
|
||||
height: 100vh;
|
||||
max-height: none;
|
||||
min-height: 100vh;
|
||||
padding: 24px;
|
||||
padding: 0px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
@ -542,9 +556,8 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.fullscreen-embed-preview {
|
||||
min-height: calc(100vh - 48px);
|
||||
height: calc(100vh - 48px);
|
||||
border-radius: 12px;
|
||||
height: 100vh;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.fullscreen-unsupported-preview {
|
||||
|
||||
@ -144,6 +144,7 @@
|
||||
:bodyStyle="{ maxHeight: '90vh', overflow: 'auto' }"
|
||||
:footer="null"
|
||||
:closable="false"
|
||||
wrapClassName="agent-file-preview-modal"
|
||||
@cancel="closePreview"
|
||||
>
|
||||
<AgentFilePreview
|
||||
@ -1110,33 +1111,6 @@ watch(useInlinePreview, (isInline) => {
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-modal) {
|
||||
z-index: 1050;
|
||||
}
|
||||
|
||||
:deep(.ant-modal-content) {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--gray-200);
|
||||
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
:deep(.ant-modal-header) {
|
||||
background: var(--main-5);
|
||||
border-bottom: 1px solid var(--gray-200);
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
:deep(.ant-modal-title) {
|
||||
font-weight: 600;
|
||||
color: var(--gray-1000);
|
||||
font-family: 'JetBrains Mono', 'Fira Code', 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||
}
|
||||
|
||||
:deep(.ant-modal-body) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* File Tree Styles - VS Code Style Refined */
|
||||
.file-tree-container {
|
||||
padding: 4px;
|
||||
@ -1199,6 +1173,10 @@ watch(useInlinePreview, (isInline) => {
|
||||
color: var(--main-600);
|
||||
}
|
||||
|
||||
.tree-delete-btn:hover:not(:disabled) {
|
||||
color: var(--error-600, #dc2626);
|
||||
}
|
||||
|
||||
/* 附件列表专用样式 */
|
||||
.attachment-tree :deep(.ant-tree-node-content-wrapper) {
|
||||
border: 1px solid var(--gray-200);
|
||||
@ -1216,3 +1194,34 @@ watch(useInlinePreview, (isInline) => {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
.agent-file-preview-modal {
|
||||
.ant-modal {
|
||||
z-index: 1050;
|
||||
.ant-modal-content {
|
||||
border-radius: 8px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--gray-200);
|
||||
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
:deep(.ant-modal-header) {
|
||||
background: var(--main-5);
|
||||
border-bottom: 1px solid var(--gray-200);
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
:deep(.ant-modal-title) {
|
||||
font-weight: 600;
|
||||
color: var(--gray-1000);
|
||||
font-family: 'JetBrains Mono', 'Fira Code', 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||
}
|
||||
|
||||
:deep(.ant-modal-body) {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user