177 lines
6.1 KiB
Python
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()
|