mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-08-25 16:46:17 +00:00
feat(web): filter subfolders in the add-workspace browser
Browsing into a folder with many subdirectories meant scrolling a long flat list. Add a live case-insensitive filter input above the folder list (shown once a folder has entries), filtering the current folder's subfolders by name, with a no-match hint and a reset on each navigation. Adds zh/en strings.
This commit is contained in:
parent
76d12cf6d6
commit
4b0eae5ab3
3 changed files with 53 additions and 1 deletions
|
|
@ -30,6 +30,14 @@ const currentPath = ref('');
|
|||
const parentPath = ref<string | null>(null);
|
||||
const entries = ref<FsBrowseEntry[]>([]);
|
||||
|
||||
// Live filter over the current folder's subfolders (case-insensitive substring).
|
||||
const filter = ref('');
|
||||
const filteredEntries = computed<FsBrowseEntry[]>(() => {
|
||||
const q = filter.value.trim().toLowerCase();
|
||||
if (q === '') return entries.value;
|
||||
return entries.value.filter((e) => e.name.toLowerCase().includes(q));
|
||||
});
|
||||
|
||||
// Paste-path escape hatch
|
||||
const pathInput = ref('');
|
||||
const pathTrimmed = computed(() => pathInput.value.trim());
|
||||
|
|
@ -63,6 +71,7 @@ async function navigate(path?: string): Promise<void> {
|
|||
currentPath.value = result.path;
|
||||
parentPath.value = result.parent;
|
||||
entries.value = result.entries;
|
||||
filter.value = ''; // a fresh folder starts unfiltered
|
||||
browseFailed.value = false;
|
||||
} catch {
|
||||
browseFailed.value = true;
|
||||
|
|
@ -153,12 +162,28 @@ onUnmounted(() => document.removeEventListener('keydown', handleKeydown));
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filter the current folder's subfolders -->
|
||||
<div v-if="!loading && entries.length > 0" class="filterbar">
|
||||
<svg class="filter-icon" width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<circle cx="7" cy="7" r="4.5"/><path d="M11 11l3 3"/>
|
||||
</svg>
|
||||
<input
|
||||
v-model="filter"
|
||||
class="filter-input"
|
||||
type="text"
|
||||
:placeholder="t('workspace.filterPlaceholder')"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
@keydown.stop
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Folder list -->
|
||||
<div class="folder-list">
|
||||
<div v-if="loading" class="fl-loading">{{ t('workspace.browsing') }}</div>
|
||||
<template v-else>
|
||||
<button
|
||||
v-for="entry in entries"
|
||||
v-for="entry in filteredEntries"
|
||||
:key="entry.path"
|
||||
class="folder-row"
|
||||
@click="openEntry(entry)"
|
||||
|
|
@ -173,6 +198,7 @@ onUnmounted(() => document.removeEventListener('keydown', handleKeydown));
|
|||
</span>
|
||||
</button>
|
||||
<div v-if="entries.length === 0" class="fl-empty">{{ t('workspace.noSubfolders') }}</div>
|
||||
<div v-else-if="filteredEntries.length === 0" class="fl-empty">{{ t('workspace.noFilterMatch', { q: filter.trim() }) }}</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -309,6 +335,28 @@ onUnmounted(() => document.removeEventListener('keydown', handleKeydown));
|
|||
.crumb:hover { color: var(--blue); background: var(--panel2); }
|
||||
.crumb.last { color: var(--ink); font-weight: 600; }
|
||||
|
||||
/* Subfolder filter */
|
||||
.filterbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 14px;
|
||||
border-bottom: 1px solid var(--line2);
|
||||
}
|
||||
.filter-icon { flex: none; color: var(--faint); }
|
||||
.filter-input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-family: var(--mono);
|
||||
font-size: 12px;
|
||||
padding: 3px 4px;
|
||||
border: none;
|
||||
background: none;
|
||||
color: var(--ink);
|
||||
outline: none;
|
||||
}
|
||||
.filter-input::placeholder { color: var(--faint); }
|
||||
|
||||
/* Folder list */
|
||||
.folder-list {
|
||||
max-height: 280px;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ export default {
|
|||
openThisFolder: 'Open this folder',
|
||||
up: 'Up',
|
||||
browsing: 'Browsing…',
|
||||
filterPlaceholder: 'Filter subfolders…',
|
||||
noFilterMatch: 'No subfolders match “{q}”',
|
||||
noSubfolders: 'No subfolders here',
|
||||
gitTag: 'git',
|
||||
browseHint: 'Click a folder to enter it, then "Open this folder" to add it as a workspace.',
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ export default {
|
|||
openThisFolder: '打开此文件夹',
|
||||
up: '上一级',
|
||||
browsing: '加载中…',
|
||||
filterPlaceholder: '过滤子文件夹…',
|
||||
noFilterMatch: '没有匹配「{q}」的子文件夹',
|
||||
noSubfolders: '此处没有子文件夹',
|
||||
gitTag: 'git',
|
||||
browseHint: '点击文件夹进入,再点"打开此文件夹"将其添加为工作区。',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue