Add section filter cancel actions
Browse files- static/app.js +34 -1
- static/index.html +6 -4
- static/style.css +7 -0
static/app.js
CHANGED
|
@@ -516,9 +516,12 @@ function cacheDOM() {
|
|
| 516 |
DOM.toast = $("#toast");
|
| 517 |
DOM.filterRepoSection = $("#filter-repo-section");
|
| 518 |
DOM.filterRepoList = $("#filter-repo-list");
|
|
|
|
| 519 |
DOM.filterFolderSection = $("#filter-folder-section");
|
| 520 |
DOM.filterFolderTree = $("#filter-folder-tree");
|
|
|
|
| 521 |
DOM.filterExtList = $("#filter-ext-list");
|
|
|
|
| 522 |
DOM.filterMinSize = $("#filter-min-size");
|
| 523 |
DOM.filterMaxSize = $("#filter-max-size");
|
| 524 |
DOM.mirrorLinksToggle = $("#mirror-links-toggle");
|
|
@@ -1811,9 +1814,16 @@ function updateStatusBar() {
|
|
| 1811 |
: (STATE.total > 0 ? `共 ${STATE.total.toLocaleString()} 条结果` : "");
|
| 1812 |
const has = STATE.filterRepos.length || STATE.filterExtensions.length || STATE.filterFolderSelfs.length || STATE.filterFolderSubtrees.length || STATE.filterMinSize !== null || STATE.filterMaxSize !== null;
|
| 1813 |
DOM.clearFiltersBtn.style.display = has ? "" : "none";
|
|
|
|
| 1814 |
if (DOM.multiToggleLabel) DOM.multiToggleLabel.style.display = STATE.total > 0 ? "" : "none";
|
| 1815 |
}
|
| 1816 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1817 |
function setSearchVisualLoading(loading) {
|
| 1818 |
document.getElementById("search-box").classList.toggle("is-searching", loading);
|
| 1819 |
updateStatusBar();
|
|
@@ -2048,7 +2058,7 @@ async function renderFilters(routeId) {
|
|
| 2048 |
} catch (e) { }
|
| 2049 |
if (routeId && routeId !== routeRenderId) return;
|
| 2050 |
const repos = Array.isArray(STATE.repoList) ? STATE.repoList : [];
|
| 2051 |
-
renderCheckboxList(DOM.filterRepoList, repos.map(r => ({ key: r.name, label: r.name.split("/").pop(), count: r.count })), STATE.filterRepos, (vals) => { STATE.filterRepos = vals; STATE.page = 1; doSearch(); });
|
| 2052 |
} else {
|
| 2053 |
DOM.filterRepoSection.style.display = "none";
|
| 2054 |
}
|
|
@@ -2120,6 +2130,7 @@ function renderExtensionFilter() {
|
|
| 2120 |
STATE.filterExtensions = vals;
|
| 2121 |
STATE.page = 1;
|
| 2122 |
saveStoredExtensionFilters();
|
|
|
|
| 2123 |
doSearch();
|
| 2124 |
});
|
| 2125 |
}
|
|
@@ -2426,6 +2437,7 @@ function persistFolderSelection(subtreeSet, selfSet) {
|
|
| 2426 |
STATE.filterFolders = merged;
|
| 2427 |
STATE.page = 1;
|
| 2428 |
STATE.results = [];
|
|
|
|
| 2429 |
syncStateToURL(true);
|
| 2430 |
doSearch();
|
| 2431 |
}
|
|
@@ -3142,6 +3154,27 @@ async function init() {
|
|
| 3142 |
DOM.themeBtn.addEventListener("click", toggleTheme);
|
| 3143 |
DOM.mobileToggleBtn.addEventListener("click", toggleMobile);
|
| 3144 |
DOM.clearFiltersBtn.addEventListener("click", clearAllFilters);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3145 |
DOM.searchFoldersToggle.addEventListener("change", () => {
|
| 3146 |
STATE.searchFolders = DOM.searchFoldersToggle.checked;
|
| 3147 |
STATE.page = 1;
|
|
|
|
| 516 |
DOM.toast = $("#toast");
|
| 517 |
DOM.filterRepoSection = $("#filter-repo-section");
|
| 518 |
DOM.filterRepoList = $("#filter-repo-list");
|
| 519 |
+
DOM.repoFilterCancel = $("#repo-filter-cancel");
|
| 520 |
DOM.filterFolderSection = $("#filter-folder-section");
|
| 521 |
DOM.filterFolderTree = $("#filter-folder-tree");
|
| 522 |
+
DOM.folderFilterCancel = $("#folder-filter-cancel");
|
| 523 |
DOM.filterExtList = $("#filter-ext-list");
|
| 524 |
+
DOM.extFilterCancel = $("#ext-filter-cancel");
|
| 525 |
DOM.filterMinSize = $("#filter-min-size");
|
| 526 |
DOM.filterMaxSize = $("#filter-max-size");
|
| 527 |
DOM.mirrorLinksToggle = $("#mirror-links-toggle");
|
|
|
|
| 1814 |
: (STATE.total > 0 ? `共 ${STATE.total.toLocaleString()} 条结果` : "");
|
| 1815 |
const has = STATE.filterRepos.length || STATE.filterExtensions.length || STATE.filterFolderSelfs.length || STATE.filterFolderSubtrees.length || STATE.filterMinSize !== null || STATE.filterMaxSize !== null;
|
| 1816 |
DOM.clearFiltersBtn.style.display = has ? "" : "none";
|
| 1817 |
+
updateFilterCancelButtons();
|
| 1818 |
if (DOM.multiToggleLabel) DOM.multiToggleLabel.style.display = STATE.total > 0 ? "" : "none";
|
| 1819 |
}
|
| 1820 |
|
| 1821 |
+
function updateFilterCancelButtons() {
|
| 1822 |
+
DOM.repoFilterCancel.hidden = STATE.filterRepos.length === 0;
|
| 1823 |
+
DOM.folderFilterCancel.hidden = STATE.filterFolderSelfs.length === 0 && STATE.filterFolderSubtrees.length === 0;
|
| 1824 |
+
DOM.extFilterCancel.hidden = STATE.filterExtensions.length === 0;
|
| 1825 |
+
}
|
| 1826 |
+
|
| 1827 |
function setSearchVisualLoading(loading) {
|
| 1828 |
document.getElementById("search-box").classList.toggle("is-searching", loading);
|
| 1829 |
updateStatusBar();
|
|
|
|
| 2058 |
} catch (e) { }
|
| 2059 |
if (routeId && routeId !== routeRenderId) return;
|
| 2060 |
const repos = Array.isArray(STATE.repoList) ? STATE.repoList : [];
|
| 2061 |
+
renderCheckboxList(DOM.filterRepoList, repos.map(r => ({ key: r.name, label: r.name.split("/").pop(), count: r.count })), STATE.filterRepos, (vals) => { STATE.filterRepos = vals; STATE.page = 1; updateFilterCancelButtons(); doSearch(); });
|
| 2062 |
} else {
|
| 2063 |
DOM.filterRepoSection.style.display = "none";
|
| 2064 |
}
|
|
|
|
| 2130 |
STATE.filterExtensions = vals;
|
| 2131 |
STATE.page = 1;
|
| 2132 |
saveStoredExtensionFilters();
|
| 2133 |
+
updateFilterCancelButtons();
|
| 2134 |
doSearch();
|
| 2135 |
});
|
| 2136 |
}
|
|
|
|
| 2437 |
STATE.filterFolders = merged;
|
| 2438 |
STATE.page = 1;
|
| 2439 |
STATE.results = [];
|
| 2440 |
+
updateFilterCancelButtons();
|
| 2441 |
syncStateToURL(true);
|
| 2442 |
doSearch();
|
| 2443 |
}
|
|
|
|
| 3154 |
DOM.themeBtn.addEventListener("click", toggleTheme);
|
| 3155 |
DOM.mobileToggleBtn.addEventListener("click", toggleMobile);
|
| 3156 |
DOM.clearFiltersBtn.addEventListener("click", clearAllFilters);
|
| 3157 |
+
DOM.repoFilterCancel.addEventListener("click", () => {
|
| 3158 |
+
STATE.filterRepos = [];
|
| 3159 |
+
STATE.page = 1;
|
| 3160 |
+
STATE.results = [];
|
| 3161 |
+
updateFilterCancelButtons();
|
| 3162 |
+
renderFilters(routeRenderId);
|
| 3163 |
+
doSearch();
|
| 3164 |
+
});
|
| 3165 |
+
DOM.folderFilterCancel.addEventListener("click", () => {
|
| 3166 |
+
persistFolderSelection(new Set(), new Set());
|
| 3167 |
+
renderFilterFolderTree();
|
| 3168 |
+
});
|
| 3169 |
+
DOM.extFilterCancel.addEventListener("click", () => {
|
| 3170 |
+
STATE.filterExtensions = [];
|
| 3171 |
+
STATE.page = 1;
|
| 3172 |
+
STATE.results = [];
|
| 3173 |
+
saveStoredExtensionFilters();
|
| 3174 |
+
updateFilterCancelButtons();
|
| 3175 |
+
renderExtensionFilter();
|
| 3176 |
+
doSearch();
|
| 3177 |
+
});
|
| 3178 |
DOM.searchFoldersToggle.addEventListener("change", () => {
|
| 3179 |
STATE.searchFolders = DOM.searchFoldersToggle.checked;
|
| 3180 |
STATE.page = 1;
|
static/index.html
CHANGED
|
@@ -190,12 +190,14 @@
|
|
| 190 |
</label>
|
| 191 |
</div>
|
| 192 |
<div id="filter-repo-section" class="filter-section">
|
| 193 |
-
<div class="filter-section-title">
|
|
|
|
|
|
|
| 194 |
<div id="filter-repo-list" class="filter-checkbox-list"></div>
|
| 195 |
</div>
|
| 196 |
<div id="filter-folder-section" class="filter-section">
|
| 197 |
<div class="filter-section-title">
|
| 198 |
-
<span>路径过滤</span>
|
| 199 |
<span class="filter-actions">
|
| 200 |
<button id="folder-select-all" class="text-btn-sm">全选</button>
|
| 201 |
<button id="folder-deselect-all" class="text-btn-sm">反选</button>
|
|
@@ -203,9 +205,9 @@
|
|
| 203 |
</div>
|
| 204 |
<div id="filter-folder-tree" class="filter-folder-tree"></div>
|
| 205 |
</div>
|
| 206 |
-
<div class="filter-section">
|
| 207 |
<div class="filter-section-title">
|
| 208 |
-
<span>文件类型</span>
|
| 209 |
<span class="filter-actions">
|
| 210 |
<button id="ext-select-all" class="text-btn-sm">全选</button>
|
| 211 |
<button id="ext-deselect-all" class="text-btn-sm">反选</button>
|
|
|
|
| 190 |
</label>
|
| 191 |
</div>
|
| 192 |
<div id="filter-repo-section" class="filter-section">
|
| 193 |
+
<div class="filter-section-title">
|
| 194 |
+
<span class="filter-title-leading"><span>仓库过滤</span><button id="repo-filter-cancel" class="text-btn-sm" hidden>取消</button></span>
|
| 195 |
+
</div>
|
| 196 |
<div id="filter-repo-list" class="filter-checkbox-list"></div>
|
| 197 |
</div>
|
| 198 |
<div id="filter-folder-section" class="filter-section">
|
| 199 |
<div class="filter-section-title">
|
| 200 |
+
<span class="filter-title-leading"><span>路径过滤</span><button id="folder-filter-cancel" class="text-btn-sm" hidden>取消</button></span>
|
| 201 |
<span class="filter-actions">
|
| 202 |
<button id="folder-select-all" class="text-btn-sm">全选</button>
|
| 203 |
<button id="folder-deselect-all" class="text-btn-sm">反选</button>
|
|
|
|
| 205 |
</div>
|
| 206 |
<div id="filter-folder-tree" class="filter-folder-tree"></div>
|
| 207 |
</div>
|
| 208 |
+
<div id="filter-ext-section" class="filter-section">
|
| 209 |
<div class="filter-section-title">
|
| 210 |
+
<span class="filter-title-leading"><span>文件类型</span><button id="ext-filter-cancel" class="text-btn-sm" hidden>取消</button></span>
|
| 211 |
<span class="filter-actions">
|
| 212 |
<button id="ext-select-all" class="text-btn-sm">全选</button>
|
| 213 |
<button id="ext-deselect-all" class="text-btn-sm">反选</button>
|
static/style.css
CHANGED
|
@@ -1151,6 +1151,13 @@ body.mobile .mobile-selected-count {
|
|
| 1151 |
.filter-actions {
|
| 1152 |
display: flex;
|
| 1153 |
gap: 4px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1154 |
}
|
| 1155 |
|
| 1156 |
.filter-checkbox-list {
|
|
|
|
| 1151 |
.filter-actions {
|
| 1152 |
display: flex;
|
| 1153 |
gap: 4px;
|
| 1154 |
+
margin-left: auto;
|
| 1155 |
+
}
|
| 1156 |
+
|
| 1157 |
+
.filter-title-leading {
|
| 1158 |
+
display: flex;
|
| 1159 |
+
align-items: center;
|
| 1160 |
+
gap: 4px;
|
| 1161 |
}
|
| 1162 |
|
| 1163 |
.filter-checkbox-list {
|