@@ -430,15 +430,116 @@ def build_history_section(
430430 app ._cal_accordion = widgets .Accordion (children = [cal_panel ], selected_index = None )
431431 app ._cal_accordion .set_title (0 , "Calibrate time estimates" )
432432
433+ # ── Search / faceted filters (HIST.7) ──────────────────────────────
434+ # All filtering is client-side over the cached ``app._history_entries``
435+ # list; widgets here only hold facet state. See app_history.apply_history_filter.
436+ from quantui .app_history import HISTORY_CALC_TYPE_FACETS , HISTORY_STATUS_FACETS
437+
438+ app ._history_entries = []
439+ app ._history_filter_suspend = False
440+ app .history_search = widgets .Text (
441+ placeholder = "search name or formula (e.g. benzene, C6H6)" ,
442+ continuous_update = True , # type-to-narrow
443+ layout = layout_fn (width = "300px" ),
444+ )
445+ app .history_filter_clear_btn = widgets .Button (
446+ icon = "times" ,
447+ tooltip = "Clear all history filters" ,
448+ layout = layout_fn (width = "40px" ),
449+ )
450+ app .history_count_lbl = widgets .HTML (
451+ '<span style="color:#888;font-size:12px"></span>'
452+ )
453+ app ._history_calc_chips = {
454+ key : widgets .ToggleButton (
455+ value = False ,
456+ description = label ,
457+ tooltip = f"Show only { label } calculations" ,
458+ layout = layout_fn (width = "auto" ),
459+ )
460+ for label , key in HISTORY_CALC_TYPE_FACETS
461+ }
462+ app .history_method_dd = widgets .Dropdown (
463+ options = [("Any method" , "" )],
464+ value = "" ,
465+ description = "Method:" ,
466+ style = {"description_width" : "55px" },
467+ layout = layout_fn (width = "200px" ),
468+ )
469+ app .history_basis_dd = widgets .Dropdown (
470+ options = [("Any basis" , "" )],
471+ value = "" ,
472+ description = "Basis:" ,
473+ style = {"description_width" : "55px" },
474+ layout = layout_fn (width = "200px" ),
475+ )
476+ app .history_date_from = widgets .DatePicker (
477+ description = "From:" ,
478+ style = {"description_width" : "45px" },
479+ layout = layout_fn (width = "200px" ),
480+ )
481+ app .history_date_to = widgets .DatePicker (
482+ description = "To:" ,
483+ style = {"description_width" : "35px" },
484+ layout = layout_fn (width = "190px" ),
485+ )
486+ app ._history_status_chips = {
487+ key : widgets .ToggleButton (
488+ value = False ,
489+ description = label ,
490+ layout = layout_fn (width = "auto" ),
491+ )
492+ for label , key in HISTORY_STATUS_FACETS
493+ }
494+
495+ def _facet_label (text : str , width : str = "60px" ) -> widgets .HTML :
496+ return widgets .HTML (
497+ f'<span style="color:#555;font-size:12px;width:{ width } ;'
498+ f'display:inline-block">{ text } </span>'
499+ )
500+
501+ app ._history_filter_box = widgets .VBox (
502+ [
503+ widgets .HBox (
504+ [
505+ app .history_search ,
506+ app .history_filter_clear_btn ,
507+ app .history_count_lbl ,
508+ ],
509+ layout = layout_fn (align_items = "center" , gap = "6px" ),
510+ ),
511+ widgets .HBox (
512+ [_facet_label ("Type:" ), * app ._history_calc_chips .values ()],
513+ layout = layout_fn (align_items = "center" , gap = "4px" , flex_wrap = "wrap" ),
514+ ),
515+ widgets .HBox (
516+ [app .history_method_dd , app .history_basis_dd ],
517+ layout = layout_fn (align_items = "center" , gap = "8px" ),
518+ ),
519+ widgets .HBox (
520+ [
521+ app .history_date_from ,
522+ app .history_date_to ,
523+ _facet_label ("Status:" , "55px" ),
524+ * app ._history_status_chips .values (),
525+ ],
526+ layout = layout_fn (align_items = "center" , gap = "6px" , flex_wrap = "wrap" ),
527+ ),
528+ ],
529+ layout = layout_fn (margin = "0 0 8px" , gap = "4px" ),
530+ )
531+
433532 # The History tab is now purely the result-browser. Performance stats
434533 # + Calibrate accordions moved to the System Settings tab — see below —
435534 # so the user finds benchmarking + system state in one logical place.
436535 app .history_panel = widgets .VBox (
437536 [
438537 widgets .HTML (
439538 '<p style="color:#555;font-size:13px;margin:0 0 8px">'
440- "Calculations are saved automatically. Select one below to view its results.</p>"
539+ "Calculations are saved automatically. Filter below, then select "
540+ "one to view its results.</p>"
441541 ),
542+ app ._history_filter_box ,
442543 widgets .HBox (
443544 [
444545 app .past_dd ,
0 commit comments