UI improvements: search dropdown, layout fixes, taller step fields
- Recipe search now shows dropdown suggestions while typing; full results load on Enter or clicking "Keresés" button - Search field moved above tag filter; active filter tags below input - Instruction textarea doubled in height (60px → 120px) on both import and edit pages Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+99
-24
@@ -30,23 +30,44 @@
|
||||
}
|
||||
|
||||
/* --- Search & filter bar --- */
|
||||
.search-bar {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
.search-section {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.search-bar .search-input-wrap {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
.search-row {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
margin-bottom: 0.75rem;
|
||||
position: relative;
|
||||
}
|
||||
.search-bar input[type="text"] {
|
||||
.search-row input[type="text"] {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.tag-filter-wrap {
|
||||
min-width: 200px;
|
||||
flex: 1;
|
||||
}
|
||||
.search-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 60px;
|
||||
background: var(--surface2);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
max-height: 250px;
|
||||
overflow-y: auto;
|
||||
z-index: 110;
|
||||
display: none;
|
||||
}
|
||||
.search-dropdown.open { display: block; }
|
||||
.search-dropdown-item {
|
||||
padding: 0.5rem 0.75rem;
|
||||
cursor: pointer;
|
||||
font-size: 0.9rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.search-dropdown-item:hover { background: var(--accent-glow); }
|
||||
.tag-filter-wrap {
|
||||
position: relative;
|
||||
}
|
||||
.tag-filter-wrap input[type="text"] {
|
||||
@@ -56,7 +77,7 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.3rem;
|
||||
margin-bottom: 0.5rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
.filter-chip {
|
||||
display: inline-flex;
|
||||
@@ -275,17 +296,19 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Search & tag filter -->
|
||||
<div class="search-bar">
|
||||
<div class="search-input-wrap">
|
||||
<!-- Search -->
|
||||
<div class="search-section">
|
||||
<div class="search-row">
|
||||
<input type="text" id="recipeSearch" placeholder="Recept keresése..."
|
||||
oninput="onSearchInput()" autocomplete="off">
|
||||
oninput="onSearchInput()" onkeydown="onSearchKeydown(event)" autocomplete="off">
|
||||
<button class="btn btn-primary" onclick="executeSearch()">Keresés</button>
|
||||
<div id="searchDropdown" class="search-dropdown"></div>
|
||||
</div>
|
||||
<div class="tag-filter-wrap">
|
||||
<div class="active-filter-tags" id="activeFilterTags"></div>
|
||||
<input type="text" id="tagFilterSearch" placeholder="Szűrés címke szerint..."
|
||||
autocomplete="off" oninput="onFilterTagSearch()" onfocus="onFilterTagSearch()">
|
||||
<div id="tagFilterDropdown" class="tag-dropdown"></div>
|
||||
<div class="active-filter-tags" id="activeFilterTags"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -371,12 +394,60 @@ function switchBackend(b) {
|
||||
function onSearchInput() {
|
||||
clearTimeout(searchTimeout);
|
||||
searchTimeout = setTimeout(() => {
|
||||
currentPage = 1;
|
||||
selectedIds.clear();
|
||||
loadRecipes();
|
||||
loadSearchSuggestions();
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function onSearchKeydown(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
document.getElementById('searchDropdown').classList.remove('open');
|
||||
executeSearch();
|
||||
} else if (e.key === 'Escape') {
|
||||
document.getElementById('searchDropdown').classList.remove('open');
|
||||
}
|
||||
}
|
||||
|
||||
function executeSearch() {
|
||||
document.getElementById('searchDropdown').classList.remove('open');
|
||||
currentPage = 1;
|
||||
selectedIds.clear();
|
||||
loadRecipes();
|
||||
}
|
||||
|
||||
async function loadSearchSuggestions() {
|
||||
const q = document.getElementById('recipeSearch').value.trim();
|
||||
const dropdown = document.getElementById('searchDropdown');
|
||||
if (!q) { dropdown.classList.remove('open'); return; }
|
||||
|
||||
const params = new URLSearchParams({ page: 1, per_page: 8, search: q });
|
||||
if (activeFilterTagIds.length) params.set('tag_ids', activeFilterTagIds.join(','));
|
||||
|
||||
try {
|
||||
const resp = await fetch('/api/recipes/' + currentBackend + '?' + params);
|
||||
const data = await resp.json();
|
||||
if (!data.ok || data.items.length === 0) {
|
||||
dropdown.classList.remove('open');
|
||||
return;
|
||||
}
|
||||
let html = '';
|
||||
for (const r of data.items) {
|
||||
html += '<div class="search-dropdown-item" onclick="selectSearchItem(\'' +
|
||||
escHtml(r.name).replace(/'/g, "\\'") + '\')">' + escHtml(r.name) + '</div>';
|
||||
}
|
||||
dropdown.innerHTML = html;
|
||||
dropdown.classList.add('open');
|
||||
} catch (e) {
|
||||
dropdown.classList.remove('open');
|
||||
}
|
||||
}
|
||||
|
||||
function selectSearchItem(name) {
|
||||
document.getElementById('recipeSearch').value = name;
|
||||
document.getElementById('searchDropdown').classList.remove('open');
|
||||
executeSearch();
|
||||
}
|
||||
|
||||
/* ===== Tag filter ===== */
|
||||
async function loadBackendTags() {
|
||||
try {
|
||||
@@ -444,12 +515,16 @@ function renderFilterChips() {
|
||||
wrap.innerHTML = html;
|
||||
}
|
||||
|
||||
/* ===== Close dropdown on outside click ===== */
|
||||
/* ===== Close dropdowns on outside click ===== */
|
||||
document.addEventListener('click', e => {
|
||||
const wrap = document.querySelector('.tag-filter-wrap');
|
||||
if (wrap && !wrap.contains(e.target)) {
|
||||
const tagWrap = document.querySelector('.tag-filter-wrap');
|
||||
if (tagWrap && !tagWrap.contains(e.target)) {
|
||||
document.getElementById('tagFilterDropdown').classList.remove('open');
|
||||
}
|
||||
const searchRow = document.querySelector('.search-row');
|
||||
if (searchRow && !searchRow.contains(e.target)) {
|
||||
document.getElementById('searchDropdown').classList.remove('open');
|
||||
}
|
||||
});
|
||||
|
||||
/* ===== Load recipes ===== */
|
||||
|
||||
Reference in New Issue
Block a user