Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions themes/bootstrap/layouts/_default/tools.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,35 @@
<div class="card text-bg-light mb-3">
<div class="card-body">
<fieldset>
<div class="mb-3">
<label class="form-label">Filter mode</label>
<div class="form-check">
<input class="form-check-input" type="radio" name="categoryMode" id="mode-any" value="any" checked>
<label class="form-check-label" for="mode-any">
<small>
<span class="tooltip">
match any
<span class="tooltip-text">
boolean OR
</span>
</span>
</small>
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="categoryMode" id="mode-all" value="all">
<label class="form-check-label" for="mode-all">
<small>
<span class="tooltip">
match all
<span class="tooltip-text">
boolean AND
</span>
</span>
</small>
</label>
</div>
</div>
<div class="mb-2">
<label class="form-label" for="search">Search</label>
<input type="search" class="form-control form-control-sm" id="search" autocomplete="off" placeholder="Keywords..."/>
Expand Down
22 changes: 21 additions & 1 deletion themes/bootstrap/static/js/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ let sortedTools = [];
let owners = new Set(); // owners, languages, categories become arrays.
let languages = new Set();
let categories = new Set();
let categoryFilterMode = 'any'; // 'any' or 'all'
const categoryModeAny = document.getElementById('mode-any');
const categoryModeAll = document.getElementById('mode-all');
const selectedLanguages = new Set();
const selectedOwners = new Set();
let selectedCategories = new Set();
Expand Down Expand Up @@ -134,7 +137,13 @@ function fillToolsTable(tools, selectedLanguages, selectedOwners) {
const ownerMatch = tool.owner.some(o => selectedOwners.has(o));
let categoryMatch;
if (useCategories) {
categoryMatch = tool.category.some(c => selectedCategories.has(c));
if (categoryFilterMode === 'any') {
// OR logic: show if ANY category matches
categoryMatch = tool.category.some(c => selectedCategories.has(c));
} else {
// AND logic: show only if ALL categories match
categoryMatch = tool.category.every(c => selectedCategories.has(c));
}
} else {
categoryMatch = true;
}
Expand Down Expand Up @@ -280,6 +289,17 @@ function initFormProcessors() {
searchResultMessage.innerHTML = LOADING_MESSAGE;
debouncedHandleCategoryCheckbox(e);
});
categoryModeAny.addEventListener('change', () => {
categoryFilterMode = 'any';
searchResultMessage.innerHTML = LOADING_MESSAGE;
fillToolsTable(sortedTools, selectedLanguages, selectedOwners);
});

categoryModeAll.addEventListener('change', () => {
categoryFilterMode = 'all';
searchResultMessage.innerHTML = LOADING_MESSAGE;
fillToolsTable(sortedTools, selectedLanguages, selectedOwners);
});
}

// Init multiselect components
Expand Down