Update page_files/Categorized_Search.py

#5
Files changed (1) hide show
  1. page_files/Categorized_Search.py +81 -53
page_files/Categorized_Search.py CHANGED
@@ -7,7 +7,15 @@ import streamlit as st
7
  from PIL import Image
8
 
9
  from data_loader import get_all_sections, load_material_data
10
-
 
 
 
 
 
 
 
 
11
  st.markdown(
12
  """
13
  <style>
@@ -375,6 +383,12 @@ def toggle_class(material_class: str):
375
  else:
376
  st.session_state.active_classes = [material_class]
377
  st.session_state.current_page = 0
 
 
 
 
 
 
378
 
379
 
380
  def visible_page_numbers(current_page: int, total_pages: int):
@@ -607,7 +621,7 @@ with left_col:
607
  disabled=st.session_state.selected_row is None,
608
  ):
609
  st.info("Open the Inspect tab on the right panel.")
610
-
611
  if st.session_state.selected_row:
612
  selected_abbr, selected_name = st.session_state.selected_row
613
  st.markdown(
@@ -649,7 +663,9 @@ with right_col:
649
  tab_materials, tab_inspect = st.tabs(
650
  ["All Materials", "Inspect"]
651
  )
652
-
 
 
653
  with tab_materials:
654
  filter_label = (
655
  ", ".join(st.session_state.active_classes)
@@ -678,11 +694,11 @@ with right_col:
678
 
679
  if not page_meta.empty:
680
  table_df = page_meta.copy()
681
- table_df["Select"] = table_df["material_abbreviation"].eq(selected_abbr)
682
  table_df["Class"] = table_df["_class"].map(class_map)
683
  table_df["Actions"] = ""
684
  table_df = table_df[
685
- ["Select", "material_name", "material_abbreviation", "Class", "Actions"]
686
  ].rename(
687
  columns={
688
  "material_name": "Material Name",
@@ -693,67 +709,57 @@ with right_col:
693
  table_df = pd.DataFrame(
694
  columns=["Select", "Material Name", "Abbreviation", "Class", "Actions"]
695
  )
 
 
696
 
 
 
 
697
 
698
-
699
- editor_df = st.data_editor(
 
700
  table_df,
701
- key=f"materials_editor_{st.session_state.current_page}",
702
- use_container_width=True,
703
  hide_index=True,
704
  height=400,
705
- row_height=46,
706
- column_order=["Select", "Material Name", "Abbreviation", "Class", "Actions"],
707
  column_config={
708
- "Select": st.column_config.CheckboxColumn("", width="small"),
709
  "Material Name": st.column_config.TextColumn("MATERIAL NAME", width="large"),
710
  "Abbreviation": st.column_config.TextColumn("ABBREVIATION", width="medium"),
711
  "Class": st.column_config.TextColumn("CLASS", width="small"),
712
  "Actions": st.column_config.TextColumn("ACTIONS", width="small"),
713
  },
714
- disabled=["Material Name", "Abbreviation", "Class", "Actions"],
715
  )
 
716
 
717
- #checked_rows = editor_df[
718
- # editor_df["Select"]
719
- # & editor_df["Abbreviation"].astype(str).str.strip().ne("")
720
- #]
721
- #if not checked_rows.empty:
722
- # chosen = checked_rows.iloc[0]
723
- # abbr = chosen["Abbreviation"]
724
- # name = chosen["Material Name"]
725
- # if (
726
- # st.session_state.selected_row is None
727
- # or st.session_state.selected_row[0] != abbr
728
- # ):
729
- # st.session_state.selected_row = (abbr, name)
730
- # st.rerun()
731
- checked_rows = editor_df[
732
- editor_df["Select"]
733
- & editor_df["Abbreviation"].astype(str).str.strip().ne("")
734
- ]
735
-
736
- if not checked_rows.empty:
737
- current_abbr = st.session_state.selected_row[0] if st.session_state.selected_row else None
738
-
739
-
740
- new_rows = checked_rows[checked_rows["Abbreviation"] != current_abbr]
741
-
742
- if not new_rows.empty:
743
- chosen = new_rows.iloc[0]
744
- else:
745
- chosen = checked_rows.iloc[0]
746
-
747
- abbr = chosen["Abbreviation"]
748
- name = chosen["Material Name"]
749
- if st.session_state.selected_row is None or st.session_state.selected_row[0] != abbr:
750
  st.session_state.selected_row = (abbr, name)
751
  st.rerun()
752
- else:
753
- if st.session_state.selected_row is not None:
 
 
 
 
754
  st.session_state.selected_row = None
 
755
  st.rerun()
756
-
 
 
 
 
757
  info_col, nav_col = st.columns([2.4, 2.0])
758
  with info_col:
759
  st.markdown(
@@ -808,14 +814,19 @@ with right_col:
808
  if st.button(
809
  label,
810
  key=f"page_btn_{idx}_{label}_{target_page}",
811
- use_container_width=True,
812
  disabled=disabled,
813
  type="primary" if active else "secondary",
814
  ):
 
 
815
  st.session_state.current_page = target_page
 
 
 
 
816
  st.rerun()
817
 
818
-
819
  with tab_inspect:
820
  if not st.session_state.selected_row:
821
  st.warning("Select a material in All Materials first.")
@@ -852,8 +863,25 @@ with right_col:
852
  .drop_duplicates()
853
  .reset_index(drop=True)
854
  )
855
- st.dataframe(properties_df, use_container_width=True, hide_index=True, height=240)
856
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
857
  property_options = properties_df["property_name"].dropna().tolist()
858
  if property_options:
859
  if st.session_state.inspect_property not in property_options:
 
7
  from PIL import Image
8
 
9
  from data_loader import get_all_sections, load_material_data
10
+ import streamlit.components.v1 as components
11
+
12
+ def switch_tab(index):
13
+ components.html(f"""
14
+ <script>
15
+ var tabs = window.parent.document.querySelectorAll('[data-testid="stTabs"] button[role="tab"]');
16
+ if (tabs.length > {index}) tabs[{index}].click();
17
+ </script>
18
+ """, height=0)
19
  st.markdown(
20
  """
21
  <style>
 
383
  else:
384
  st.session_state.active_classes = [material_class]
385
  st.session_state.current_page = 0
386
+ st.session_state.selected_row = None
387
+ st.session_state["last_synced_abbr"] = None
388
+ df_key = f"materials_df_0"
389
+ if df_key in st.session_state:
390
+ st.session_state[df_key] = {"selection": {"rows": [], "columns": [], "cells": []}}
391
+ st.session_state["_switch_to_tab"] = 0
392
 
393
 
394
  def visible_page_numbers(current_page: int, total_pages: int):
 
621
  disabled=st.session_state.selected_row is None,
622
  ):
623
  st.info("Open the Inspect tab on the right panel.")
624
+ switch_tab(1)
625
  if st.session_state.selected_row:
626
  selected_abbr, selected_name = st.session_state.selected_row
627
  st.markdown(
 
663
  tab_materials, tab_inspect = st.tabs(
664
  ["All Materials", "Inspect"]
665
  )
666
+ if st.session_state.get("_switch_to_tab") is not None:
667
+ switch_tab(st.session_state["_switch_to_tab"])
668
+ del st.session_state["_switch_to_tab"]
669
  with tab_materials:
670
  filter_label = (
671
  ", ".join(st.session_state.active_classes)
 
694
 
695
  if not page_meta.empty:
696
  table_df = page_meta.copy()
697
+
698
  table_df["Class"] = table_df["_class"].map(class_map)
699
  table_df["Actions"] = ""
700
  table_df = table_df[
701
+ [ "material_name", "material_abbreviation", "Class", "Actions"]
702
  ].rename(
703
  columns={
704
  "material_name": "Material Name",
 
709
  table_df = pd.DataFrame(
710
  columns=["Select", "Material Name", "Abbreviation", "Class", "Actions"]
711
  )
712
+
713
+ df_key = f"materials_df_{st.session_state.current_page}"
714
 
715
+ if "pending_row_select" in st.session_state:
716
+ st.session_state[df_key] = {"selection": {"rows": [st.session_state.pending_row_select], "columns": [], "cells": []}}
717
+ del st.session_state["pending_row_select"]
718
 
719
+ if st.session_state.pop("_clear_df_selection", False):
720
+ st.session_state[df_key] = {"selection": {"rows": [], "columns": [], "cells": []}}
721
+ event = st.dataframe(
722
  table_df,
723
+ key=df_key,
724
+ width="stretch",
725
  hide_index=True,
726
  height=400,
727
+ on_select="rerun",
728
+ selection_mode=["single-cell", "single-row"],
729
  column_config={
 
730
  "Material Name": st.column_config.TextColumn("MATERIAL NAME", width="large"),
731
  "Abbreviation": st.column_config.TextColumn("ABBREVIATION", width="medium"),
732
  "Class": st.column_config.TextColumn("CLASS", width="small"),
733
  "Actions": st.column_config.TextColumn("ACTIONS", width="small"),
734
  },
 
735
  )
736
+
737
 
738
+ selected_rows = event.selection.rows
739
+ selected_cells = event.selection.cells
740
+
741
+ if selected_rows:
742
+ row_idx = selected_rows[0]
743
+ chosen = page_meta.iloc[row_idx]
744
+ abbr = chosen["material_abbreviation"]
745
+ name = chosen["material_name"]
746
+ if not (st.session_state.selected_row and st.session_state.selected_row[0] == abbr):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747
  st.session_state.selected_row = (abbr, name)
748
  st.rerun()
749
+ if selected_cells:
750
+ row_idx = selected_cells[0][0]
751
+ chosen = page_meta.iloc[row_idx]
752
+ abbr = chosen["material_abbreviation"]
753
+ name = chosen["material_name"]
754
+ if st.session_state.selected_row and st.session_state.selected_row[0] == abbr:
755
  st.session_state.selected_row = None
756
+ st.session_state["pending_row_select"] = None
757
  st.rerun()
758
+ elif st.session_state.selected_row is None or st.session_state.selected_row[0] != abbr:
759
+ st.session_state.selected_row = (abbr, name)
760
+ st.session_state["pending_row_select"] = row_idx
761
+ st.rerun()
762
+
763
  info_col, nav_col = st.columns([2.4, 2.0])
764
  with info_col:
765
  st.markdown(
 
814
  if st.button(
815
  label,
816
  key=f"page_btn_{idx}_{label}_{target_page}",
817
+ width="stretch",
818
  disabled=disabled,
819
  type="primary" if active else "secondary",
820
  ):
821
+ old_page = st.session_state.current_page
822
+
823
  st.session_state.current_page = target_page
824
+ st.session_state.selected_row = None
825
+ st.session_state["last_synced_abbr"] = None
826
+ st.session_state["_clear_df_selection"] = True
827
+
828
  st.rerun()
829
 
 
830
  with tab_inspect:
831
  if not st.session_state.selected_row:
832
  st.warning("Select a material in All Materials first.")
 
863
  .drop_duplicates()
864
  .reset_index(drop=True)
865
  )
866
+ #st.dataframe(properties_df, use_container_width=True, hide_index=True, height=240)
867
+ rows_html = "".join(
868
+ f"<tr><td style='padding:8px 12px;font-size:0.82rem;color:#111827;border-bottom:1px solid #f8fafc;'>{row['property_name']}</td>"
869
+ f"<td style='padding:8px 12px;font-size:0.82rem;color:#64748b;border-bottom:1px solid #f8fafc;'>{row['section']}</td></tr>"
870
+ for _, row in properties_df.iterrows()
871
+ )
872
+ st.markdown(f"""
873
+ <div style='border:1px solid #edf2f7;border-radius:8px;overflow:hidden;max-height:240px;overflow-y:auto;'>
874
+ <table style='width:100%;border-collapse:collapse;'>
875
+ <thead>
876
+ <tr style='background:#f8fafc;'>
877
+ <th style='padding:8px 12px;font-size:0.64rem;font-weight:700;letter-spacing:1px;color:#94a3b8;text-align:left;border-bottom:1px solid #edf2f7;'>PROPERTY NAME</th>
878
+ <th style='padding:8px 12px;font-size:0.64rem;font-weight:700;letter-spacing:1px;color:#94a3b8;text-align:left;border-bottom:1px solid #edf2f7;'>SECTION</th>
879
+ </tr>
880
+ </thead>
881
+ <tbody>{rows_html}</tbody>
882
+ </table>
883
+ </div>
884
+ """, unsafe_allow_html=True)
885
  property_options = properties_df["property_name"].dropna().tolist()
886
  if property_options:
887
  if st.session_state.inspect_property not in property_options: