Add auto-expand vault functionality to sidebar filter with improved clear button visibility and restructured input layouts for both search and filter components
This commit is contained in:
parent
3a86450a73
commit
d9add8dcba
@ -623,20 +623,31 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Sidebar filter
|
// Sidebar filter
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
function initSidebarFilter() {
|
async function initSidebarFilter() {
|
||||||
const input = document.getElementById("sidebar-filter-input");
|
const input = document.getElementById("sidebar-filter-input");
|
||||||
const caseBtn = document.getElementById("sidebar-filter-case-btn");
|
const caseBtn = document.getElementById("sidebar-filter-case-btn");
|
||||||
const clearBtn = document.getElementById("sidebar-filter-clear-btn");
|
const clearBtn = document.getElementById("sidebar-filter-clear-btn");
|
||||||
|
|
||||||
input.addEventListener("input", () => {
|
input.addEventListener("input", async () => {
|
||||||
|
const hasText = input.value.length > 0;
|
||||||
|
clearBtn.style.display = hasText ? "flex" : "none";
|
||||||
|
|
||||||
|
if (hasText) {
|
||||||
|
// Expand all vaults and load their contents for filtering
|
||||||
|
await expandAllVaultsForFiltering();
|
||||||
|
}
|
||||||
|
|
||||||
const q = sidebarFilterCaseSensitive ? input.value.trim() : input.value.trim().toLowerCase();
|
const q = sidebarFilterCaseSensitive ? input.value.trim() : input.value.trim().toLowerCase();
|
||||||
filterSidebarTree(q);
|
filterSidebarTree(q);
|
||||||
filterTagCloud(q);
|
filterTagCloud(q);
|
||||||
});
|
});
|
||||||
|
|
||||||
caseBtn.addEventListener("click", () => {
|
caseBtn.addEventListener("click", async () => {
|
||||||
sidebarFilterCaseSensitive = !sidebarFilterCaseSensitive;
|
sidebarFilterCaseSensitive = !sidebarFilterCaseSensitive;
|
||||||
caseBtn.classList.toggle("active");
|
caseBtn.classList.toggle("active");
|
||||||
|
if (input.value.trim()) {
|
||||||
|
await expandAllVaultsForFiltering();
|
||||||
|
}
|
||||||
const q = sidebarFilterCaseSensitive ? input.value.trim() : input.value.trim().toLowerCase();
|
const q = sidebarFilterCaseSensitive ? input.value.trim() : input.value.trim().toLowerCase();
|
||||||
filterSidebarTree(q);
|
filterSidebarTree(q);
|
||||||
filterTagCloud(q);
|
filterTagCloud(q);
|
||||||
@ -644,11 +655,26 @@
|
|||||||
|
|
||||||
clearBtn.addEventListener("click", () => {
|
clearBtn.addEventListener("click", () => {
|
||||||
input.value = "";
|
input.value = "";
|
||||||
|
clearBtn.style.display = "none";
|
||||||
sidebarFilterCaseSensitive = false;
|
sidebarFilterCaseSensitive = false;
|
||||||
caseBtn.classList.remove("active");
|
caseBtn.classList.remove("active");
|
||||||
filterSidebarTree("");
|
filterSidebarTree("");
|
||||||
filterTagCloud("");
|
filterTagCloud("");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Initially hide clear button
|
||||||
|
clearBtn.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
async function expandAllVaultsForFiltering() {
|
||||||
|
const vaultItems = document.querySelectorAll(".vault-item");
|
||||||
|
for (const vaultItem of vaultItems) {
|
||||||
|
const vaultName = vaultItem.getAttribute("data-vault");
|
||||||
|
const childContainer = document.getElementById(`vault-children-${vaultName}`);
|
||||||
|
if (childContainer && childContainer.classList.contains("collapsed")) {
|
||||||
|
await toggleVault(vaultItem, vaultName, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterSidebarTree(query) {
|
function filterSidebarTree(query) {
|
||||||
@ -1263,7 +1289,13 @@
|
|||||||
const caseBtn = document.getElementById("search-case-btn");
|
const caseBtn = document.getElementById("search-case-btn");
|
||||||
const clearBtn = document.getElementById("search-clear-btn");
|
const clearBtn = document.getElementById("search-clear-btn");
|
||||||
|
|
||||||
|
// Initially hide clear button
|
||||||
|
clearBtn.style.display = "none";
|
||||||
|
|
||||||
input.addEventListener("input", () => {
|
input.addEventListener("input", () => {
|
||||||
|
const hasText = input.value.length > 0;
|
||||||
|
clearBtn.style.display = hasText ? "flex" : "none";
|
||||||
|
|
||||||
clearTimeout(searchTimeout);
|
clearTimeout(searchTimeout);
|
||||||
searchTimeout = setTimeout(() => {
|
searchTimeout = setTimeout(() => {
|
||||||
const q = input.value.trim();
|
const q = input.value.trim();
|
||||||
@ -1284,6 +1316,7 @@
|
|||||||
|
|
||||||
clearBtn.addEventListener("click", () => {
|
clearBtn.addEventListener("click", () => {
|
||||||
input.value = "";
|
input.value = "";
|
||||||
|
clearBtn.style.display = "none";
|
||||||
searchCaseSensitive = false;
|
searchCaseSensitive = false;
|
||||||
caseBtn.classList.remove("active");
|
caseBtn.classList.remove("active");
|
||||||
showWelcome();
|
showWelcome();
|
||||||
|
|||||||
@ -78,7 +78,9 @@
|
|||||||
<div class="header-center">
|
<div class="header-center">
|
||||||
<div class="search-wrapper">
|
<div class="search-wrapper">
|
||||||
<i data-lucide="search" class="search-icon" style="width:16px;height:16px"></i>
|
<i data-lucide="search" class="search-icon" style="width:16px;height:16px"></i>
|
||||||
|
<div class="search-input-wrapper">
|
||||||
<input type="text" id="search-input" placeholder="Recherche..." autocomplete="off">
|
<input type="text" id="search-input" placeholder="Recherche..." autocomplete="off">
|
||||||
|
<div class="search-actions">
|
||||||
<button class="search-btn" id="search-case-btn" type="button" title="Respecter la casse" aria-label="Respecter la casse">
|
<button class="search-btn" id="search-case-btn" type="button" title="Respecter la casse" aria-label="Respecter la casse">
|
||||||
<span>Aa</span>
|
<span>Aa</span>
|
||||||
</button>
|
</button>
|
||||||
@ -87,6 +89,8 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<div class="header-menu">
|
<div class="header-menu">
|
||||||
@ -158,7 +162,9 @@
|
|||||||
<!-- Sidebar filter -->
|
<!-- Sidebar filter -->
|
||||||
<div class="sidebar-filter">
|
<div class="sidebar-filter">
|
||||||
<i data-lucide="filter" class="sidebar-filter-icon" style="width:14px;height:14px"></i>
|
<i data-lucide="filter" class="sidebar-filter-icon" style="width:14px;height:14px"></i>
|
||||||
|
<div class="sidebar-filter-input-wrapper">
|
||||||
<input type="text" id="sidebar-filter-input" placeholder="Filtrer fichiers et tags..." autocomplete="off">
|
<input type="text" id="sidebar-filter-input" placeholder="Filtrer fichiers et tags..." autocomplete="off">
|
||||||
|
<div class="sidebar-filter-actions">
|
||||||
<button class="sidebar-filter-btn" id="sidebar-filter-case-btn" type="button" title="Respecter la casse" aria-label="Respecter la casse">
|
<button class="sidebar-filter-btn" id="sidebar-filter-case-btn" type="button" title="Respecter la casse" aria-label="Respecter la casse">
|
||||||
<span>Aa</span>
|
<span>Aa</span>
|
||||||
</button>
|
</button>
|
||||||
@ -166,6 +172,8 @@
|
|||||||
<i data-lucide="x" style="width:14px;height:14px"></i>
|
<i data-lucide="x" style="width:14px;height:14px"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="custom-dropdown sidebar-dropdown" id="vault-quick-select-dropdown">
|
<div class="custom-dropdown sidebar-dropdown" id="vault-quick-select-dropdown">
|
||||||
<button class="custom-dropdown-trigger" type="button" aria-haspopup="listbox" aria-expanded="false">
|
<button class="custom-dropdown-trigger" type="button" aria-haspopup="listbox" aria-expanded="false">
|
||||||
|
|||||||
@ -153,11 +153,27 @@ a:hover {
|
|||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-wrapper input {
|
.search-wrapper .search-icon {
|
||||||
|
position: absolute;
|
||||||
|
left: 10px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input-wrapper {
|
||||||
|
position: relative;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input-wrapper input {
|
||||||
|
width: 100%;
|
||||||
padding: 8px 14px 8px 38px;
|
padding: 8px 14px 8px 38px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
@ -168,26 +184,29 @@ a:hover {
|
|||||||
outline: none;
|
outline: none;
|
||||||
transition: border-color 200ms ease, background 200ms ease;
|
transition: border-color 200ms ease, background 200ms ease;
|
||||||
}
|
}
|
||||||
.search-wrapper input:focus {
|
|
||||||
|
.search-input-wrapper input:focus {
|
||||||
border-color: var(--accent);
|
border-color: var(--accent);
|
||||||
}
|
}
|
||||||
.search-wrapper .search-icon {
|
|
||||||
|
.search-actions {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 10px;
|
right: 4px;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
color: var(--text-secondary);
|
display: flex;
|
||||||
pointer-events: none;
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-btn {
|
.search-btn {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 32px;
|
width: 28px;
|
||||||
height: 32px;
|
height: 28px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 6px;
|
border-radius: 4px;
|
||||||
background: var(--bg-secondary);
|
background: var(--bg-secondary);
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -196,6 +215,7 @@ a:hover {
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
transition: all 150ms ease;
|
transition: all 150ms ease;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-btn:hover {
|
.search-btn:hover {
|
||||||
@ -554,8 +574,16 @@ select {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
}
|
}
|
||||||
.sidebar-filter input {
|
|
||||||
|
.sidebar-filter-input-wrapper {
|
||||||
|
position: relative;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-filter-input-wrapper input {
|
||||||
|
width: 100%;
|
||||||
padding: 6px 10px 6px 32px;
|
padding: 6px 10px 6px 32px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
@ -566,31 +594,44 @@ select {
|
|||||||
outline: none;
|
outline: none;
|
||||||
transition: border-color 200ms ease;
|
transition: border-color 200ms ease;
|
||||||
}
|
}
|
||||||
.sidebar-filter input:focus {
|
|
||||||
|
.sidebar-filter-input-wrapper input:focus {
|
||||||
border-color: var(--accent);
|
border-color: var(--accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-filter-icon {
|
.sidebar-filter-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 22px;
|
left: 10px;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-filter-actions {
|
||||||
|
position: absolute;
|
||||||
|
right: 4px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-filter-btn {
|
.sidebar-filter-btn {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 28px;
|
width: 24px;
|
||||||
height: 28px;
|
height: 24px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: var(--bg-secondary);
|
background: var(--bg-secondary);
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.7rem;
|
font-size: 0.65rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
transition: all 150ms ease;
|
transition: all 150ms ease;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user