Simplify sidebar tabs, improve saved search display, and refactor
suggestions
This commit is contained in:
parent
1c59300f11
commit
0d3de28967
@ -453,52 +453,48 @@
|
||||
const historyItems = SearchHistory.filter(inputValue);
|
||||
this._renderHistory(historyItems, inputValue);
|
||||
|
||||
// Title and tag suggestions from API (debounced)
|
||||
// Title and tag suggestions from API (debounced) — always fetch both
|
||||
clearTimeout(this._suggestTimer);
|
||||
if (ctx.prefix && ctx.prefix.length >= 2) {
|
||||
this._suggestTimer = setTimeout(() => this._fetchSuggestions(ctx, vault, inputValue), SUGGEST_DEBOUNCE_MS);
|
||||
const prefix = ctx.prefix;
|
||||
if (prefix && prefix.length >= 2) {
|
||||
this._suggestTimer = setTimeout(() => this._fetchSuggestions(prefix, vault), 150);
|
||||
} else {
|
||||
this._renderTitles([], "");
|
||||
this._renderTags([], "");
|
||||
this._titlesSection.hidden = true;
|
||||
this._tagsSection.hidden = true;
|
||||
}
|
||||
|
||||
// Show/hide sections
|
||||
this._titlesSection.hidden = true;
|
||||
this._tagsSection.hidden = true;
|
||||
const hasContent = historyItems.length > 0;
|
||||
this._historySection.hidden = historyItems.length === 0;
|
||||
this._emptyEl.hidden = hasContent;
|
||||
|
||||
if (hasContent || (ctx.prefix && ctx.prefix.length >= 2)) {
|
||||
if (hasContent || (prefix && prefix.length >= 2)) {
|
||||
this.show();
|
||||
} else if (!hasContent) {
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
|
||||
this._collectItems();
|
||||
},
|
||||
|
||||
async _fetchSuggestions(ctx, vault, inputValue) {
|
||||
async _fetchSuggestions(prefix, vault) {
|
||||
suggestAbortController = new AbortController();
|
||||
try {
|
||||
const [titlesRes, tagsRes] = await Promise.all([
|
||||
ctx.type !== "tag" ? api(`/api/suggest?q=${encodeURIComponent(ctx.prefix)}&vault=${encodeURIComponent(vault)}&limit=8`, { signal: suggestAbortController.signal }) : Promise.resolve({ suggestions: [] }),
|
||||
ctx.type === "tag" || ctx.type === "text" ? api(`/api/tags/suggest?q=${encodeURIComponent(ctx.prefix)}&vault=${encodeURIComponent(vault)}&limit=6`, { signal: suggestAbortController.signal }) : Promise.resolve({ suggestions: [] }),
|
||||
api(`/api/suggest?q=${encodeURIComponent(prefix)}&vault=${encodeURIComponent(vault)}&limit=8`, { signal: suggestAbortController.signal }),
|
||||
api(`/api/tags/suggest?q=${encodeURIComponent(prefix)}&vault=${encodeURIComponent(vault)}&limit=8`, { signal: suggestAbortController.signal }),
|
||||
]);
|
||||
|
||||
this._renderTitles(titlesRes.suggestions || [], ctx.prefix);
|
||||
this._renderTags(tagsRes.suggestions || [], ctx.prefix);
|
||||
this._renderTitles(titlesRes.suggestions || [], prefix);
|
||||
this._renderTags(tagsRes.suggestions || [], prefix);
|
||||
|
||||
// Update visibility
|
||||
const hasTitles = (titlesRes.suggestions || []).length > 0;
|
||||
const hasTags = (tagsRes.suggestions || []).length > 0;
|
||||
this._titlesSection.hidden = !hasTitles;
|
||||
this._tagsSection.hidden = !hasTags;
|
||||
|
||||
const historyVisible = !this._historySection.hidden;
|
||||
const hasAny = historyVisible || hasTitles || hasTags;
|
||||
this._emptyEl.hidden = hasAny;
|
||||
if (hasAny) this.show();
|
||||
else if (!historyVisible) this.hide();
|
||||
|
||||
if (hasTitles || hasTags) this.show();
|
||||
this._collectItems();
|
||||
} catch (err) {
|
||||
if (err.name !== "AbortError") console.error("Suggestion fetch error:", err);
|
||||
@ -6056,18 +6052,26 @@
|
||||
return;
|
||||
}
|
||||
if (empty) empty.style.display = "none";
|
||||
list.innerHTML = searches.map(s => `
|
||||
list.innerHTML = searches.map(s => {
|
||||
const badges = [];
|
||||
if (s.case_sensitive) badges.push('<span class="search-filter-badge">Aa</span>');
|
||||
if (s.whole_word) badges.push('<span class="search-filter-badge">wd</span>');
|
||||
if (s.regex) badges.push('<span class="search-filter-badge">.*</span>');
|
||||
const pathFilters = [];
|
||||
if (s.include_paths) pathFilters.push(`<span class="saved-search-path" title="Inclure: ${escapeHtml(s.include_paths)}">📥 ${escapeHtml(s.include_paths)}</span>`);
|
||||
if (s.exclude_paths) pathFilters.push(`<span class="saved-search-path" title="Exclure: ${escapeHtml(s.exclude_paths)}">📤 ${escapeHtml(s.exclude_paths)}</span>`);
|
||||
const vaultStr = s.vault && s.vault !== "all" ? `<span class="saved-search-vault">📁 ${escapeHtml(s.vault)}</span>` : "";
|
||||
return `
|
||||
<div class="saved-search-item">
|
||||
<div class="saved-search-query" title="${escapeHtml(s.query)}">${escapeHtml(s.query.length > 50 ? s.query.slice(0, 50) + "..." : s.query)}</div>
|
||||
<div class="saved-search-query">${escapeHtml(s.query)}</div>
|
||||
<div class="saved-search-meta">
|
||||
${s.case_sensitive ? '<span class="search-filter-badge">Aa</span>' : ""}
|
||||
${s.whole_word ? '<span class="search-filter-badge">wd</span>' : ""}
|
||||
${s.regex ? '<span class="search-filter-badge">.*</span>' : ""}
|
||||
<span class="saved-search-vault">${escapeHtml(s.vault)}</span>
|
||||
${badges.join("")}
|
||||
${vaultStr}
|
||||
</div>
|
||||
${pathFilters.length ? '<div class="saved-search-filters">' + pathFilters.join(" ") + '</div>' : ""}
|
||||
<button class="saved-search-delete" data-id="${s.id}" title="Supprimer">✕</button>
|
||||
</div>
|
||||
`).join("");
|
||||
`}).join("");
|
||||
list.querySelectorAll(".saved-search-item").forEach(item => {
|
||||
item.addEventListener("click", (e) => {
|
||||
if (e.target.classList.contains("saved-search-delete")) return;
|
||||
@ -6090,6 +6094,7 @@
|
||||
if (excl) excl.value = s.exclude_paths;
|
||||
}
|
||||
// Execute the search
|
||||
AutocompleteDropdown.hide();
|
||||
const vault = s.vault || "all";
|
||||
if (input) { input.dispatchEvent(new Event("input")); }
|
||||
clearTimeout(searchTimeout);
|
||||
|
||||
@ -306,24 +306,20 @@
|
||||
<!-- Tab bar -->
|
||||
<div class="sidebar-tabs" role="tablist" aria-label="Sections sidebar">
|
||||
<button class="sidebar-tab active" id="sidebar-tab-vaults" role="tab"
|
||||
aria-selected="true" aria-controls="sidebar-panel-vaults" data-tab="vaults">
|
||||
<i data-lucide="folder-tree" style="width:13px;height:13px"></i>
|
||||
<span>Vaults</span>
|
||||
aria-selected="true" aria-controls="sidebar-panel-vaults" data-tab="vaults" title="Vaults">
|
||||
<i data-lucide="folder-tree" style="width:18px;height:18px"></i>
|
||||
</button>
|
||||
<button class="sidebar-tab" id="sidebar-tab-tags" role="tab"
|
||||
aria-selected="false" aria-controls="sidebar-panel-tags" data-tab="tags">
|
||||
<i data-lucide="tag" style="width:13px;height:13px"></i>
|
||||
<span>Tags</span>
|
||||
aria-selected="false" aria-controls="sidebar-panel-tags" data-tab="tags" title="Tags">
|
||||
<i data-lucide="tag" style="width:18px;height:18px"></i>
|
||||
</button>
|
||||
<button class="sidebar-tab" id="sidebar-tab-recent" role="tab"
|
||||
aria-selected="false" aria-controls="sidebar-panel-recent" data-tab="recent">
|
||||
<i data-lucide="clock" style="width:13px;height:13px"></i>
|
||||
<span>Récent</span>
|
||||
aria-selected="false" aria-controls="sidebar-panel-recent" data-tab="recent" title="Récent">
|
||||
<i data-lucide="clock" style="width:18px;height:18px"></i>
|
||||
</button>
|
||||
<button class="sidebar-tab" id="sidebar-tab-saved" role="tab"
|
||||
aria-selected="false" aria-controls="sidebar-panel-saved" data-tab="saved">
|
||||
<i data-lucide="bookmark" style="width:13px;height:13px"></i>
|
||||
<span>Sauvegardes</span>
|
||||
aria-selected="false" aria-controls="sidebar-panel-saved" data-tab="saved" title="Sauvegardes">
|
||||
<i data-lucide="bookmark" style="width:18px;height:18px"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@ -755,23 +755,14 @@ select {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
padding: 9px 8px 8px;
|
||||
padding: 8px 4px 6px;
|
||||
border: none;
|
||||
border-bottom: 2px solid transparent;
|
||||
background: transparent;
|
||||
color: var(--text-muted);
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.07em;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
color 150ms ease,
|
||||
border-color 150ms ease;
|
||||
transition: color 150ms ease, border-color 150ms ease;
|
||||
margin-bottom: -1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.sidebar-tab:hover {
|
||||
@ -1854,24 +1845,25 @@ select {
|
||||
transition:
|
||||
background 120ms ease,
|
||||
border-color 120ms ease;
|
||||
position: relative;
|
||||
}
|
||||
.search-result-item:hover {
|
||||
background: var(--bg-hover);
|
||||
border-color: var(--accent);
|
||||
position: relative;
|
||||
}
|
||||
.search-result-ext {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 10px;
|
||||
font-size: 0.6rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.65rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-muted);
|
||||
background: var(--bg-hover);
|
||||
padding: 1px 6px;
|
||||
border-radius: 3px;
|
||||
color: var(--accent);
|
||||
background: var(--accent-bg, rgba(99, 102, 241, 0.12));
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
letter-spacing: 0.5px;
|
||||
border: 1px solid rgba(99, 102, 241, 0.2);
|
||||
}
|
||||
.search-filters-row {
|
||||
display: flex;
|
||||
@ -1910,42 +1902,65 @@ select {
|
||||
|
||||
/* Saved searches sidebar */
|
||||
.saved-search-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 8px 10px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: background 0.15s;
|
||||
position: relative;
|
||||
padding: 10px 12px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
transition: background 0.15s;
|
||||
border: 1px solid transparent;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.saved-search-item:hover { background: var(--bg-hover); }
|
||||
.saved-search-item:hover { background: var(--bg-hover); border-color: var(--border); }
|
||||
.saved-search-query {
|
||||
flex: 1;
|
||||
font-size: 0.8rem;
|
||||
font-size: 0.82rem;
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
line-height: 1.4;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.saved-search-meta {
|
||||
display: flex;
|
||||
gap: 3px;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.saved-search-vault {
|
||||
font-size: 0.65rem;
|
||||
color: var(--text-muted);
|
||||
margin-left: 4px;
|
||||
padding: 1px 5px;
|
||||
background: var(--bg-secondary);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.saved-search-filters {
|
||||
font-size: 0.65rem;
|
||||
color: var(--accent);
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.saved-search-path {
|
||||
font-size: 0.6rem;
|
||||
color: #059669;
|
||||
background: rgba(5,150,105,0.08);
|
||||
padding: 1px 5px;
|
||||
border-radius: 3px;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.saved-search-delete {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 8px;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-muted);
|
||||
cursor: pointer;
|
||||
font-size: 0.8rem;
|
||||
padding: 2px 4px;
|
||||
font-size: 0.9rem;
|
||||
padding: 2px 6px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user