facebook-tool/gui/tabs/settings/settings_tab.py

177 lines
6.1 KiB
Python

from functools import partial
from PyQt6.QtWidgets import (
QWidget,
QVBoxLayout,
QTableWidget,
QTableWidgetItem,
QHBoxLayout,
QLabel,
QPushButton,
QMessageBox,
QMenu,
QHeaderView,
QLineEdit,
)
from PyQt6.QtCore import Qt
from services.core.loading_service import run_with_progress
from database.models.setting import Setting
from .forms.setting_form import SettingForm
PAGE_SIZE = 10
class SettingsTab(QWidget):
def __init__(self):
super().__init__()
self.current_page = 0
self.total_count = 0
self.total_pages = 0
self.sort_by = "key"
self.sort_order = "ASC"
layout = QVBoxLayout()
# --- Top layout (placeholder cho search/filter nếu cần) ---
top_layout = QHBoxLayout()
top_layout.addStretch()
layout.addLayout(top_layout)
# --- Table ---
self.table = QTableWidget()
self.table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
self.table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
layout.addWidget(self.table)
# --- Pagination ---
pag_layout = QHBoxLayout()
self.prev_btn = QPushButton("Previous")
self.prev_btn.clicked.connect(self.prev_page)
pag_layout.addWidget(self.prev_btn)
self.page_info_label = QLabel("Page 1 / 1 (0 items)")
pag_layout.addWidget(self.page_info_label)
self.page_input = QLineEdit()
self.page_input.setFixedWidth(50)
self.page_input.setPlaceholderText("Page")
self.page_input.returnPressed.connect(self.go_to_page)
pag_layout.addWidget(self.page_input)
self.next_btn = QPushButton("Next")
self.next_btn.clicked.connect(self.next_page)
pag_layout.addWidget(self.next_btn)
layout.addLayout(pag_layout)
self.setLayout(layout)
# ----------------------------------------------------------------------
def load_data(self, show_progress=True):
"""Nạp dữ liệu setting vào bảng"""
self.table.clearContents()
self.table.setRowCount(0)
offset = self.current_page * PAGE_SIZE
settings, total_count = Setting.get_paginated(
offset, PAGE_SIZE, sort_by=self.sort_by, sort_order=self.sort_order
)
self.total_count = total_count
self.total_pages = max(1, (total_count + PAGE_SIZE - 1) // PAGE_SIZE)
self.table.setColumnCount(4)
self.table.setHorizontalHeaderLabels(["ID", "Key", "Value", "Action"])
self.table.setRowCount(len(settings))
def handler(s, i_row):
setting_id = s.get("id")
key = s.get("key")
value = s.get("value") or ""
type_ = s.get("type") or "text"
# ID
id_item = QTableWidgetItem(str(setting_id))
id_item.setFlags(id_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
self.table.setItem(i_row, 0, id_item)
# Key
key_item = QTableWidgetItem(key)
key_item.setFlags(key_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
self.table.setItem(i_row, 1, key_item)
# Value
value_item = QTableWidgetItem(value)
self.table.setItem(i_row, 2, value_item)
# Action
btn_menu = QPushButton("Action")
btn_menu.setMaximumWidth(120)
menu = QMenu(btn_menu)
act_edit = menu.addAction("Edit")
act_edit.triggered.connect(
partial(self.edit_setting, setting_id, key, i_row, type_)
)
btn_menu.setMenu(menu)
self.table.setCellWidget(i_row, 3, btn_menu)
items_with_index = [(s, i) for i, s in enumerate(settings)]
if show_progress:
run_with_progress(
items_with_index,
handler=lambda x: handler(*x),
message="Loading settings...",
parent=self,
)
else:
for item in items_with_index:
handler(*item)
# --- Resize header ---
header = self.table.horizontalHeader()
header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents) # ID
header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch) # Key
header.setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch) # Value
header.setSectionResizeMode(3, QHeaderView.ResizeMode.Fixed) # Action
self.table.setColumnWidth(3, 120)
# --- Pagination ---
self.prev_btn.setEnabled(self.current_page > 0)
self.next_btn.setEnabled(self.current_page < self.total_pages - 1)
self.page_info_label.setText(
f"Page {self.current_page + 1} / {self.total_pages} ({self.total_count} items)"
)
# ----------------------------------------------------------------------
def edit_setting(self, setting_id, key, row, type_):
"""Chỉnh sửa giá trị setting"""
old_value = self.table.item(row, 2).text()
new_value = SettingForm.get_new_value(key, old_value, type_=type_, parent=self)
if new_value is not None and new_value != old_value:
try:
Setting.update_value(setting_id, new_value)
self.table.item(row, 2).setText(new_value)
except Exception as e:
QMessageBox.critical(self, "Error", f"Failed to update setting: {e}")
# ----------------------------------------------------------------------
def go_to_page(self):
"""Nhảy đến trang cụ thể"""
try:
page = int(self.page_input.text()) - 1
if 0 <= page < self.total_pages:
self.current_page = page
self.load_data()
except ValueError:
pass
def next_page(self):
"""Trang kế"""
if self.current_page < self.total_pages - 1:
self.current_page += 1
self.load_data()
def prev_page(self):
"""Trang trước"""
if self.current_page > 0:
self.current_page -= 1
self.load_data()