fixed tag search result area

This commit is contained in:
Gamosoft 2025-12-06 18:40:28 +01:00
parent b13f7820e4
commit 54762bafe0
2 changed files with 122 additions and 103 deletions

View File

@ -36,6 +36,7 @@ function noteApp() {
appName: 'NoteDiscovery', appName: 'NoteDiscovery',
appTagline: 'Your Self-Hosted Knowledge Base', appTagline: 'Your Self-Hosted Knowledge Base',
appVersion: '0.0.0', appVersion: '0.0.0',
authEnabled: false,
notes: [], notes: [],
currentNote: '', currentNote: '',
currentNoteName: '', currentNoteName: '',
@ -465,6 +466,7 @@ function noteApp() {
this.appName = config.name; this.appName = config.name;
this.appTagline = config.tagline; this.appTagline = config.tagline;
this.appVersion = config.version || '0.0.0'; this.appVersion = config.version || '0.0.0';
this.authEnabled = config.authentication?.enabled || false;
} catch (error) { } catch (error) {
console.error('Failed to load config:', error); console.error('Failed to load config:', error);
} }

View File

@ -633,7 +633,13 @@
background: none; background: none;
border: none; border: none;
cursor: pointer; cursor: pointer;
transition: color 0.15s ease; transition: color 0.15s ease, background-color 0.15s ease;
min-width: 44px;
min-height: 44px;
}
.mobile-bottom-tab:active {
background-color: var(--bg-hover);
} }
.mobile-bottom-tab.active { .mobile-bottom-tab.active {
@ -649,10 +655,6 @@
font-size: 10px; font-size: 10px;
} }
/* Add padding to main content for bottom tabs */
.main-content-mobile-padding {
padding-bottom: 56px;
}
} }
@media (min-width: 769px) { @media (min-width: 769px) {
@ -982,6 +984,7 @@
:class="{'active': activePanel === 'files'}" :class="{'active': activePanel === 'files'}"
@click="activePanel = 'files'" @click="activePanel = 'files'"
title="Files" title="Files"
aria-label="Files panel"
> >
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"></path>
@ -994,6 +997,7 @@
:class="{'active': activePanel === 'search'}" :class="{'active': activePanel === 'search'}"
@click="activePanel = 'search'" @click="activePanel = 'search'"
title="Search" title="Search"
aria-label="Search panel"
> >
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
@ -1001,6 +1005,7 @@
<!-- Search results badge --> <!-- Search results badge -->
<span <span
x-show="searchQuery.trim() && searchResults.length > 0" x-show="searchQuery.trim() && searchResults.length > 0"
x-cloak
class="absolute -top-1 -right-1 w-4 h-4 text-[9px] font-bold rounded-full flex items-center justify-center" class="absolute -top-1 -right-1 w-4 h-4 text-[9px] font-bold rounded-full flex items-center justify-center"
style="background-color: var(--accent-primary); color: white;" style="background-color: var(--accent-primary); color: white;"
x-text="searchResults.length > 9 ? '9+' : searchResults.length" x-text="searchResults.length > 9 ? '9+' : searchResults.length"
@ -1013,6 +1018,7 @@
:class="{'active': activePanel === 'tags'}" :class="{'active': activePanel === 'tags'}"
@click="activePanel = 'tags'" @click="activePanel = 'tags'"
title="Tags" title="Tags"
aria-label="Tags panel"
> >
<svg fill="currentColor" viewBox="0 0 20 20"> <svg fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M17.707 9.293a1 1 0 010 1.414l-7 7a1 1 0 01-1.414 0l-7-7A.997.997 0 012 10V5a3 3 0 013-3h5c.256 0 .512.098.707.293l7 7zM5 6a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/> <path fill-rule="evenodd" d="M17.707 9.293a1 1 0 010 1.414l-7 7a1 1 0 01-1.414 0l-7-7A.997.997 0 012 10V5a3 3 0 013-3h5c.256 0 .512.098.707.293l7 7zM5 6a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
@ -1020,6 +1026,7 @@
<!-- Selected tags badge --> <!-- Selected tags badge -->
<span <span
x-show="selectedTags.length > 0" x-show="selectedTags.length > 0"
x-cloak
class="absolute -top-1 -right-1 w-4 h-4 text-[9px] font-bold rounded-full flex items-center justify-center" class="absolute -top-1 -right-1 w-4 h-4 text-[9px] font-bold rounded-full flex items-center justify-center"
style="background-color: var(--accent-primary); color: white;" style="background-color: var(--accent-primary); color: white;"
x-text="selectedTags.length" x-text="selectedTags.length"
@ -1034,6 +1041,7 @@
:class="{'active': showGraph}" :class="{'active': showGraph}"
@click="showGraph = true; initGraph()" @click="showGraph = true; initGraph()"
title="Graph View" title="Graph View"
aria-label="Graph view"
> >
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path>
@ -1046,6 +1054,7 @@
:class="{'active': activePanel === 'settings'}" :class="{'active': activePanel === 'settings'}"
@click="activePanel = 'settings'" @click="activePanel = 'settings'"
title="Settings" title="Settings"
aria-label="Settings panel"
> >
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path>
@ -1281,8 +1290,10 @@
</button> </button>
</div> </div>
<!-- Tag List --> <!-- Scrollable content: Tags + Filtered Results -->
<div class="flex-1 overflow-y-auto custom-scrollbar p-3"> <div class="flex-1 overflow-y-auto custom-scrollbar">
<!-- Tag Chips -->
<div class="p-3">
<template x-if="Object.keys(allTags).length > 0"> <template x-if="Object.keys(allTags).length > 0">
<div class="flex flex-wrap gap-1.5"> <div class="flex flex-wrap gap-1.5">
<template x-for="[tag, count] in sortedTags" :key="tag"> <template x-for="[tag, count] in sortedTags" :key="tag">
@ -1311,13 +1322,13 @@
</template> </template>
</div> </div>
<!-- Filtered Notes (shown when tags selected) --> <!-- Filtered Notes (shown immediately after tags when selected) -->
<template x-if="selectedTags.length > 0"> <template x-if="selectedTags.length > 0">
<div class="flex-shrink-0 border-t" style="border-color: var(--border-primary); max-height: 40%;"> <div class="border-t" style="border-color: var(--border-primary);">
<div class="px-3 py-2 text-xs font-semibold uppercase tracking-wide" style="color: var(--text-tertiary);"> <div class="px-3 py-2 text-xs font-semibold uppercase tracking-wide" style="color: var(--text-tertiary);">
Filtered Notes (<span x-text="searchResults.length"></span>) Filtered Notes (<span x-text="searchResults.length"></span>)
</div> </div>
<div class="overflow-y-auto custom-scrollbar" style="max-height: 200px;"> <div>
<template x-for="note in searchResults" :key="note.path"> <template x-for="note in searchResults" :key="note.path">
<div <div
@click="openItem(note.path, note.type)" @click="openItem(note.path, note.type)"
@ -1326,7 +1337,7 @@
onmouseover="if(this.style.backgroundColor !== 'var(--accent-light)') this.style.backgroundColor='var(--bg-hover)'" onmouseover="if(this.style.backgroundColor !== 'var(--accent-light)') this.style.backgroundColor='var(--bg-hover)'"
onmouseout="if(this.style.backgroundColor !== 'var(--accent-light)') this.style.backgroundColor='transparent'" onmouseout="if(this.style.backgroundColor !== 'var(--accent-light)') this.style.backgroundColor='transparent'"
> >
<span class="truncate" x-text="note.name"></span> <span class="truncate block" x-text="note.name"></span>
</div> </div>
</template> </template>
<div x-show="searchResults.length === 0" class="px-3 py-4 text-center text-xs" style="color: var(--text-tertiary);"> <div x-show="searchResults.length === 0" class="px-3 py-4 text-center text-xs" style="color: var(--text-tertiary);">
@ -1336,10 +1347,12 @@
</div> </div>
</template> </template>
</div> </div>
</div>
<!-- END TAGS PANEL --> <!-- END TAGS PANEL -->
<!-- ==================== SETTINGS PANEL ==================== --> <!-- ==================== SETTINGS PANEL ==================== -->
<div x-show="activePanel === 'settings'" x-transition:enter="transition ease-out duration-150" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" class="flex flex-col h-full"> <template x-if="activePanel === 'settings'">
<div class="flex flex-col h-full">
<!-- Settings Header --> <!-- Settings Header -->
<div class="flex-shrink-0 px-3 py-2 border-b" style="border-color: var(--border-primary);"> <div class="flex-shrink-0 px-3 py-2 border-b" style="border-color: var(--border-primary);">
<span class="text-xs font-semibold uppercase tracking-wide" style="color: var(--text-tertiary);">Settings</span> <span class="text-xs font-semibold uppercase tracking-wide" style="color: var(--text-tertiary);">Settings</span>
@ -1361,8 +1374,7 @@
</select> </select>
</div> </div>
<!-- Logout (if auth enabled) --> <!-- Logout (if auth enabled) - uses authEnabled from main app state -->
<div x-data="{ authEnabled: false }" x-init="fetch('/api/config').then(r => r.json()).then(d => authEnabled = d.authentication?.enabled || false)">
<div x-show="authEnabled" class="mb-4"> <div x-show="authEnabled" class="mb-4">
<label class="block text-xs font-medium mb-2" style="color: var(--text-secondary);">Account</label> <label class="block text-xs font-medium mb-2" style="color: var(--text-secondary);">Account</label>
<a <a
@ -1376,7 +1388,6 @@
</a> </a>
</div> </div>
</div> </div>
</div>
<!-- Footer Info --> <!-- Footer Info -->
<div class="flex-shrink-0 p-3 border-t text-center" style="border-color: var(--border-primary);"> <div class="flex-shrink-0 p-3 border-t text-center" style="border-color: var(--border-primary);">
@ -1396,6 +1407,7 @@
</a> </a>
</div> </div>
</div> </div>
</template>
<!-- END SETTINGS PANEL --> <!-- END SETTINGS PANEL -->
</div> </div>
@ -2231,13 +2243,14 @@
</div> </div>
<!-- Mobile Bottom Tabs --> <!-- Mobile Bottom Tabs -->
<div class="mobile-bottom-tabs" style="display: none;"> <nav class="mobile-bottom-tabs" style="display: none;" role="navigation" aria-label="Main navigation">
<button <button
class="mobile-bottom-tab" class="mobile-bottom-tab"
:class="{'active': activePanel === 'files'}" :class="{'active': activePanel === 'files'}"
@click="activePanel = 'files'; mobileSidebarOpen = true;" @click="activePanel = 'files'; mobileSidebarOpen = true;"
aria-label="Files"
> >
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"></path>
</svg> </svg>
<span>Files</span> <span>Files</span>
@ -2246,8 +2259,9 @@
class="mobile-bottom-tab" class="mobile-bottom-tab"
:class="{'active': activePanel === 'search'}" :class="{'active': activePanel === 'search'}"
@click="activePanel = 'search'; mobileSidebarOpen = true;" @click="activePanel = 'search'; mobileSidebarOpen = true;"
aria-label="Search"
> >
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg> </svg>
<span>Search</span> <span>Search</span>
@ -2256,8 +2270,9 @@
class="mobile-bottom-tab" class="mobile-bottom-tab"
:class="{'active': activePanel === 'tags'}" :class="{'active': activePanel === 'tags'}"
@click="activePanel = 'tags'; mobileSidebarOpen = true;" @click="activePanel = 'tags'; mobileSidebarOpen = true;"
aria-label="Tags"
> >
<svg fill="currentColor" viewBox="0 0 20 20"> <svg fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
<path fill-rule="evenodd" d="M17.707 9.293a1 1 0 010 1.414l-7 7a1 1 0 01-1.414 0l-7-7A.997.997 0 012 10V5a3 3 0 013-3h5c.256 0 .512.098.707.293l7 7zM5 6a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/> <path fill-rule="evenodd" d="M17.707 9.293a1 1 0 010 1.414l-7 7a1 1 0 01-1.414 0l-7-7A.997.997 0 012 10V5a3 3 0 013-3h5c.256 0 .512.098.707.293l7 7zM5 6a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
</svg> </svg>
<span>Tags</span> <span>Tags</span>
@ -2266,8 +2281,9 @@
class="mobile-bottom-tab" class="mobile-bottom-tab"
:class="{'active': showGraph}" :class="{'active': showGraph}"
@click="showGraph = true; initGraph(); mobileSidebarOpen = false;" @click="showGraph = true; initGraph(); mobileSidebarOpen = false;"
aria-label="Graph"
> >
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path>
</svg> </svg>
<span>Graph</span> <span>Graph</span>
@ -2276,14 +2292,15 @@
class="mobile-bottom-tab" class="mobile-bottom-tab"
:class="{'active': activePanel === 'settings'}" :class="{'active': activePanel === 'settings'}"
@click="activePanel = 'settings'; mobileSidebarOpen = true;" @click="activePanel = 'settings'; mobileSidebarOpen = true;"
aria-label="Settings"
> >
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
</svg> </svg>
<span>Settings</span> <span>Settings</span>
</button> </button>
</div> </nav>
<script src="/static/app.js"></script> <script src="/static/app.js"></script>
</body> </body>