update search

This commit is contained in:
Ross
2026-07-11 11:01:57 +01:00
parent 9f70f3994c
commit 6642181ce1
3 changed files with 732 additions and 378 deletions
+97 -40
View File
@@ -169,41 +169,82 @@ def search_page() -> None: # build UI
with ui.row().classes('gap-2'):
ui.button('Open Output Dir', icon='folder', on_click=lambda: open_output_dir(), color='secondary').props('outline')
# Main Search Box Card
with ui.card().classes('w-full p-6 shadow-xl'):
with ui.row().classes('w-full items-center gap-4'):
# Single search box
qval_input = ui.input(
label='Search Query',
placeholder='Type search terms...'
).classes('flex-grow').props('outlined label-slot')
qval_input.add_slot('append', '<q-icon name="search" />')
# Match mode select
mode_select = ui.select(
options={'exact': 'Exact Match', 'fuzzy': 'Fuzzy Match', 'stemming': 'Stemming (Related Words)'},
value='exact',
label='Match Mode'
).classes('w-56').props('outlined')
# Targets select
targets_select = ui.select(
options={
'Title': 'Title',
'Content': 'Content',
'Breadcrumbs': 'Breadcrumbs',
'Authors': 'Authors',
'Keywords': 'Keywords',
'Category': 'Category',
'Type': 'Type'
},
value=['Title', 'Content', 'Breadcrumbs', 'Keywords', 'Category', 'Type'],
label='Search Targets',
multiple=True
).classes('w-80').props('outlined use-chips')
# Search button
search_btn = ui.button('Search', icon='search', on_click=lambda: asyncio.create_task(run_search_handler())).classes('bg-blue-600 hover:bg-blue-700 text-white font-semibold py-4 px-8 rounded-lg shadow-md transition-all duration-300')
# Main Search card
queries = [
{
'qval': '',
'mode': 'exact',
'targets': ['Title', 'Content', 'Breadcrumbs', 'Keywords', 'Category', 'Type']
}
]
with ui.card().classes('w-full p-6 shadow-xl gap-4'):
query_blocks_container = ui.column().classes('w-full gap-4')
def render_query_blocks():
query_blocks_container.clear()
with query_blocks_container:
for idx, q in enumerate(queries):
with ui.row().classes('w-full items-center gap-4 border border-slate-800 p-4 rounded-lg bg-slate-900/40 relative'):
label_text = "Query 1 (Primary)" if idx == 0 else f"OR Query {idx + 1}"
ui.label(label_text).classes('text-blue-400 font-semibold w-36')
# Bind value and update on change
qval_input = ui.input(
label='Search Query',
placeholder='Type search terms...',
value=q['qval'],
on_change=lambda e, q=q: q.update({'qval': e.value})
).classes('flex-grow').props('outlined dense').on('keydown.enter', lambda: asyncio.create_task(run_search_handler()))
mode_select = ui.select(
options={'exact': 'Exact Match', 'fuzzy': 'Fuzzy Match', 'stemming': 'Stemming (Related Words)'},
value=q['mode'],
label='Match Mode',
on_change=lambda e, q=q: q.update({'mode': e.value})
).classes('w-48').props('outlined dense')
targets_select = ui.select(
options={
'Title': 'Title',
'Content': 'Content',
'Breadcrumbs': 'Breadcrumbs',
'Authors': 'Authors',
'Keywords': 'Keywords',
'Category': 'Category',
'Type': 'Type'
},
value=q['targets'],
label='Search Targets',
multiple=True,
on_change=lambda e, q=q: q.update({'targets': e.value})
).classes('w-72').props('outlined dense use-chips')
if idx > 0:
ui.button(
icon='delete',
on_click=lambda _, idx=idx: remove_query_block(idx)
).classes('text-red-400 hover:text-red-500').props('flat round dense')
def add_query_block():
queries.append({
'qval': '',
'mode': 'exact',
'targets': ['Title', 'Content', 'Breadcrumbs', 'Keywords', 'Category', 'Type']
})
render_query_blocks()
def remove_query_block(idx: int):
if 0 < idx < len(queries):
queries.pop(idx)
render_query_blocks()
# Render initial query blocks
render_query_blocks()
with ui.row().classes('w-full justify-between items-center gap-4 mt-2'):
ui.button('Add OR Query', icon='add', on_click=add_query_block).classes('text-blue-400 border border-blue-800').props('outline dense')
search_btn = ui.button('Search', icon='search', on_click=lambda: asyncio.create_task(run_search_handler())).classes('bg-blue-600 hover:bg-blue-700 text-white font-semibold py-3 px-8 rounded-lg shadow-md transition-all duration-300')
# Advanced Criteria Expansion Box
with ui.expansion('Advanced Configurations', icon='settings').classes('w-full text-slate-300 border border-slate-800 rounded-lg p-2'):
@@ -283,7 +324,12 @@ def search_page() -> None: # build UI
''')
async def run_search_handler():
if not qval_input.value:
has_query = False
for q in queries:
if q['qval'].strip():
has_query = True
break
if not has_query:
ui.notify('Please enter a search query', color='warning')
return
@@ -291,13 +337,24 @@ def search_page() -> None: # build UI
search_btn.set_enabled(False)
try:
or_queries_param = []
for q in queries:
if q['qval'].strip():
or_queries_param.append({
'qkey': key_select.value,
'qval': q['qval'],
'mode': q['mode'],
'targets': [t.lower() for t in q['targets']]
})
results = await anyio.to_thread.run_sync(
search_md.run_search,
root_input.value,
key_select.value,
qval_input.value,
mode_select.value,
targets_select.value
'global',
'',
'exact',
None,
or_queries_param
)
table.rows = results