検索バーを検索窓へ途中

This commit is contained in:
joe 2026-02-24 10:29:10 +09:00
parent 0f86ee14ac
commit ccd549dc0c

188
main.py
View file

@ -243,6 +243,9 @@ class FlutterStyleDashboard:
self._pending_stamp_target: Optional[str] = None
self._stamp_picker: Optional[ft.FilePicker] = None
self.max_active_bank_accounts = 2
self.is_explorer_controls_visible = False
self.is_search_overlay_visible = False
self._search_field: Optional[ft.TextField] = None
self.edit_button_style = ft.ButtonStyle(
bgcolor=ft.Colors.WHITE,
color=ft.Colors.BLUE_GREY_800,
@ -366,6 +369,16 @@ class FlutterStyleDashboard:
visible=False,
)
self.page.overlay.append(self.settings_drawer_overlay)
self._search_field = ft.TextField(
value="",
hint_text="顧客名・伝票番号・備考を検索",
border=ft.InputBorder.NONE,
text_style=ft.TextStyle(size=16, color=ft.Colors.BLUE_GREY_900),
cursor_color=ft.Colors.BLUE_GREY_700,
on_submit=lambda e: self._apply_search_query(e.control.value),
)
self.search_overlay = self._build_search_overlay()
self.page.overlay.append(self.search_overlay)
# 初期表示
self.update_main_content()
@ -788,7 +801,9 @@ class FlutterStyleDashboard:
show_back=False,
show_edit=False,
trailing_controls=[
ft.IconButton(ft.Icons.REFRESH, on_click=lambda _: self.refresh_invoices()),
ft.IconButton(ft.Icons.TUNE, tooltip="詳細フィルタ", on_click=self.toggle_explorer_controls),
ft.IconButton(ft.Icons.SEARCH, tooltip="検索", on_click=self.open_search_overlay),
ft.IconButton(ft.Icons.REFRESH, tooltip="再読込", on_click=lambda _: self.refresh_invoices()),
],
leading_control=settings_button,
)
@ -806,22 +821,56 @@ class FlutterStyleDashboard:
expand=True,
padding=ft.Padding.all(16)
),
# デバッグ用: スナック表示テストボタン(一覧画面下部)
ft.Container(
content=ft.Row([
ft.Button(
content=ft.Text("スナックテストを表示"),
on_click=lambda _: self._show_snack("テストスナック"),
),
ft.Text("コンソールに 'show_snack: テストスナック' が出ればハンドラは動作", size=12, color=ft.Colors.BLUE_GREY_600),
], spacing=12),
padding=ft.Padding.symmetric(horizontal=16, vertical=8),
),
], expand=True)
logging.info("_build_invoice_list_screen: Column作成完了")
return result
def refresh_invoices(self):
logging.info("refresh_invoices")
try:
self.setup_database()
self.explorer_state.offset = 0
self.update_main_content()
self._show_snack("一覧を更新しました", ft.Colors.BLUE_GREY_600)
except Exception as e:
logging.error(f"refresh_invoices error: {e}")
self._show_snack("再読込に失敗しました", ft.Colors.RED_200)
def toggle_explorer_controls(self, _=None):
self.is_explorer_controls_visible = not self.is_explorer_controls_visible
self.update_main_content()
def open_search_overlay(self, _=None):
if not hasattr(self, "search_overlay"):
return
self.is_search_overlay_visible = True
self._search_field.value = self.explorer_state.query
self.search_overlay.visible = True
self.page.update()
self.page.set_focus(self._search_field)
def close_search_overlay(self, _=None):
if not hasattr(self, "search_overlay"):
return
self.is_search_overlay_visible = False
self.search_overlay.visible = False
self.page.update()
def _apply_search_query(self, value: Optional[str] = None):
query = (value if value is not None else self._search_field.value or "").strip()
self.explorer_state.query = query
self.explorer_state.offset = 0
self.close_search_overlay()
self.update_main_content()
def _prefill_search_keyword(self, keyword: str):
if not self._search_field:
return
self._search_field.value = keyword
self.page.update()
self.page.set_focus(self._search_field)
@log_wrap("_build_invoice_detail_screen")
def _build_invoice_detail_screen(self) -> ft.Column:
"""伝票詳細画面を構築"""
@ -1034,82 +1083,61 @@ class FlutterStyleDashboard:
logging.error(f"チェーン検証エラー: {e}")
explorer_controls = ft.Container(
content=ft.Column(
content=ft.Row(
[
ft.Row(
[
ft.TextField(
label="検索",
hint_text="伝票番号 / 顧客名 / 種別 / 備考",
value=self.explorer_state.query,
prefix_icon=ft.Icons.SEARCH,
on_change=on_query_change,
expand=True,
dense=True,
),
ft.Dropdown(
label="期間",
value=self.explorer_state.period_key,
options=[
ft.dropdown.Option(k, v)
for k, v in EXPLORER_PERIODS.items()
],
on_select=on_period_change,
width=140,
dense=True,
),
ft.Dropdown(
label="ソート",
value=self.explorer_state.sort_key,
options=[
ft.dropdown.Option(k, v)
for k, v in EXPLORER_SORTS.items()
],
on_select=on_sort_change,
width=150,
dense=True,
),
ft.IconButton(
icon=ft.Icons.ARROW_DOWNWARD if self.explorer_state.sort_desc else ft.Icons.ARROW_UPWARD,
tooltip="並び順切替",
on_click=on_sort_direction_toggle,
),
],
spacing=8,
ft.TextField(
value=self.explorer_state.query,
hint_text="",
prefix_icon=ft.Icons.SEARCH,
on_change=on_query_change,
expand=True,
dense=True,
height=38,
border=ft.InputBorder.OUTLINE,
text_style=ft.TextStyle(size=12),
content_padding=ft.Padding.symmetric(horizontal=8, vertical=0),
),
ft.Row(
[
ft.Text("赤伝", size=10, color=ft.Colors.WHITE),
ft.Switch(
value=self.explorer_state.include_offsets,
on_change=on_toggle_offsets,
),
ft.Container(width=10),
ft.Text("保存後詳細に留まる", size=10, color=ft.Colors.WHITE),
ft.Switch(
value=self.stay_on_detail_after_save,
on_change=lambda e: setattr(self, 'stay_on_detail_after_save', bool(e.control.value)),
),
ft.Text(
f"表示中: {len(slips)}件 / offset={self.explorer_state.offset}",
size=12,
color=ft.Colors.BLUE_GREY_700,
),
ft.Container(expand=True),
ft.TextButton("◀ 前", on_click=on_prev_page),
ft.TextButton("次 ▶", on_click=on_next_page),
ft.OutlinedButton("マスタ編集", on_click=self.open_master_editor),
ft.OutlinedButton("チェーン検証", on_click=on_verify_chain),
ft.Dropdown(
value=self.explorer_state.period_key,
options=[
ft.dropdown.Option(k, v)
for k, v in EXPLORER_PERIODS.items()
],
alignment=ft.MainAxisAlignment.START,
vertical_alignment=ft.CrossAxisAlignment.CENTER,
on_select=on_period_change,
width=120,
dense=True,
border=ft.InputBorder.OUTLINE,
),
ft.Dropdown(
value=self.explorer_state.sort_key,
options=[
ft.dropdown.Option(k, v)
for k, v in EXPLORER_SORTS.items()
],
on_select=on_sort_change,
width=130,
dense=True,
border=ft.InputBorder.OUTLINE,
),
ft.IconButton(
icon=ft.Icons.ARROW_DOWNWARD if self.explorer_state.sort_desc else ft.Icons.ARROW_UPWARD,
tooltip="並び順切替",
on_click=on_sort_direction_toggle,
),
ft.Text(
f"{len(slips)}", size=12, color=ft.Colors.BLUE_GREY_600,
),
ft.TextButton("", on_click=on_prev_page, tooltip="前へ"),
ft.TextButton("", on_click=on_next_page, tooltip="次へ"),
ft.IconButton(ft.Icons.VERIFIED, tooltip="チェーン検証", on_click=on_verify_chain),
],
spacing=6,
spacing=8,
vertical_alignment=ft.CrossAxisAlignment.CENTER,
),
padding=ft.Padding.all(10),
padding=ft.Padding.symmetric(horizontal=10, vertical=8),
bgcolor=ft.Colors.BLUE_GREY_50,
border_radius=8,
visible=self.is_explorer_controls_visible,
)
if not slips: