Skip to content

Commit a991e4f

Browse files
dynamicheartclaude
andcommitted
Feat: mark loaded subdirectories in sidebar and recent dropdown
- Show green check icon for loaded subdirs in DirBrowserDrawer - Display loaded count in parent node label (e.g. "export (3/5)") - Show "5 个子目录 · 已加载 2" in recent dropdown for browse-mode entries - Update loaded count in real-time after each subdir finishes loading Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent cef80c7 commit a991e4f

4 files changed

Lines changed: 43 additions & 6 deletions

File tree

llm-eval-viewer/src/components/DirBrowserDrawer.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@
4040
<el-icon v-if="!data.isLeaf" style="margin-right: 4px">
4141
<Folder />
4242
</el-icon>
43-
<el-icon v-else style="margin-right: 4px">
44-
<Document />
43+
<el-icon v-else style="margin-right: 4px" :color="loadedKeys.has(data.id) ? 'var(--ev-color-success, #67c23a)' : undefined">
44+
<Check v-if="loadedKeys.has(data.id)" />
45+
<Document v-else />
4546
</el-icon>
4647
{{ node.label }}
4748
</span>
@@ -56,7 +57,7 @@
5657

5758
<script setup>
5859
import { ref, onMounted, onBeforeUnmount } from 'vue';
59-
import { Folder, Document, ArrowLeft, ArrowRight, QuestionFilled } from '@element-plus/icons-vue';
60+
import { Folder, Document, ArrowLeft, ArrowRight, QuestionFilled, Check } from '@element-plus/icons-vue';
6061
6162
const STORAGE_KEY = 'dir_sidebar_width';
6263
const COLLAPSED_KEY = 'dir_sidebar_collapsed';
@@ -69,6 +70,7 @@ defineProps({
6970
dirTree: { type: Array, default: () => [] },
7071
currentNodeKey: { type: String, default: '' },
7172
hint: { type: String, default: '' },
73+
loadedKeys: { type: Set, default: () => new Set() },
7274
});
7375
7476
const emit = defineEmits(['select-run', 'resize']);

llm-eval-viewer/src/i18n/en.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ export default {
509509
scanning: 'Scanning...',
510510
noValidSubDirs: 'No valid subdirectories found (must contain .jsonl.gz files)',
511511
subDirCount: '{count} subdirectories',
512+
loaded: '{count} loaded',
512513
toolCount: 'Tool Count',
513514
},
514515
};

llm-eval-viewer/src/i18n/zh-CN.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ export default {
508508
scanning: '正在扫描...',
509509
noValidSubDirs: '未找到有效的子目录(子目录需包含 .jsonl.gz 文件)',
510510
subDirCount: '{count} 个子目录',
511+
loaded: '已加载 {count}',
511512
toolCount: '工具调用数',
512513
},
513514
};

llm-eval-viewer/src/views/HevalView.vue

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
:visible="showSidebar"
77
:dir-tree="subDirs"
88
:current-node-key="currentSubDir"
9+
:loaded-keys="loadedSubDirs"
910
@select-run="onSelectSubDir"
1011
@resize="w => sidebarWidth = w"
1112
/>
@@ -25,7 +26,7 @@
2526
<el-tag v-if="d.mode === 'directory'" size="small" type="info" style="margin-left: 6px">{{ $t('hyeval.browseDirectory') }}</el-tag>
2627
</div>
2728
<div class="recent-item-meta">
28-
<template v-if="d.mode === 'directory'">{{ $t('hyeval.subDirCount', { count: d.records }) }}</template>
29+
<template v-if="d.mode === 'directory'">{{ $t('hyeval.subDirCount', { count: d.records }) }}<template v-if="d.loaded"> · {{ $t('hyeval.loaded', { count: d.loaded }) }}</template></template>
2930
<template v-else>{{ d.records }} {{ $t('hyeval.records') }}</template>
3031
· {{ formatTime(d.time) }}
3132
</div>
@@ -405,6 +406,7 @@ export default {
405406
currentSubDir: localStorage.getItem('hyeval_current_subdir') || '',
406407
sidebarWidth: 0,
407408
loadGeneration: 0,
409+
loadedSubDirs: new Set(),
408410
};
409411
},
410412
@@ -621,7 +623,9 @@ export default {
621623
updateRecentDirs(name, recordCount, mode) {
622624
const MAX = 40;
623625
const list = this.recentDirs.filter(d => d.name !== name);
624-
list.unshift({ name, time: Date.now(), records: recordCount || 0, mode: mode || 'file' });
626+
const entry = { name, time: Date.now(), records: recordCount || 0, mode: mode || 'file' };
627+
if (mode === 'directory') entry.loaded = this.loadedSubDirs.size;
628+
list.unshift(entry);
625629
if (list.length > MAX) list.length = MAX;
626630
this.recentDirs = list;
627631
localStorage.setItem('hyeval_recent_dirs', JSON.stringify(list));
@@ -820,9 +824,16 @@ export default {
820824
return;
821825
}
822826
dirs.sort((a, b) => b.label.localeCompare(a.label));
827+
const loaded = new Set();
828+
await Promise.all(dirs.map(async (d) => {
829+
const cached = await this.getJudgeCache(`hyeval_v${CACHE_VERSION}_judge_${d.label}`);
830+
if (cached) loaded.add(d.label);
831+
}));
832+
this.loadedSubDirs = loaded;
833+
const parentLabel = `${parentHandle.name} (${loaded.size}/${dirs.length})`;
823834
this.subDirs = [{
824835
id: `parent_${parentHandle.name}`,
825-
label: parentHandle.name,
836+
label: parentLabel,
826837
children: dirs,
827838
}];
828839
this.browseMode = 'directory';
@@ -853,6 +864,20 @@ export default {
853864
await this.loadDirectory(node.handle);
854865
},
855866
867+
updateSidebarLabel() {
868+
if (!this.subDirs.length) return;
869+
const root = this.subDirs[0];
870+
const total = root.children ? root.children.length : 0;
871+
const name = this.parentDirHandle ? this.parentDirHandle.name : root.label.replace(/ \(.*\)$/, '');
872+
root.label = `${name} (${this.loadedSubDirs.size}/${total})`;
873+
this.subDirs = [...this.subDirs];
874+
const idx = this.recentDirs.findIndex(d => d.name === name && d.mode === 'directory');
875+
if (idx !== -1) {
876+
this.recentDirs[idx].loaded = this.loadedSubDirs.size;
877+
localStorage.setItem('hyeval_recent_dirs', JSON.stringify(this.recentDirs));
878+
}
879+
},
880+
856881
formatTime(ts) {
857882
if (!ts) return '';
858883
const d = new Date(ts);
@@ -1106,6 +1131,10 @@ export default {
11061131
this.msgCountMap = cachedMsg;
11071132
this.diagMap = cachedDiag;
11081133
this.toolCallMap = cachedTool;
1134+
if (this.browseMode === 'directory' && fn) {
1135+
this.loadedSubDirs.add(fn);
1136+
this.updateSidebarLabel();
1137+
}
11091138
return;
11101139
}
11111140
@@ -1169,6 +1198,10 @@ export default {
11691198
await this.setJudgeCache(msgCacheKey, msgMap);
11701199
await this.setJudgeCache(diagCacheKey, diagMapLocal);
11711200
await this.setJudgeCache(toolCacheKey, toolMap);
1201+
if (this.browseMode === 'directory' && fn) {
1202+
this.loadedSubDirs.add(fn);
1203+
this.updateSidebarLabel();
1204+
}
11721205
},
11731206
11741207
async getJudgeCache(key) {

0 commit comments

Comments
 (0)