Laos-Natural-Science-Chatbot / teacher_panel.py
Heng2004's picture
Update teacher_panel.py
3d2ee11 verified
# teacher_panel.py
from typing import List, Tuple
import gradio as gr # ⬅️ needed for gr.SelectData type
import qa_store
from qa_store import normalize_question
from loader import (
generate_new_manual_id,
save_manual_qa_file,
rebuild_combined_qa,
manual_qa_table_data,
)
def _table() -> List[List[str]]:
return manual_qa_table_data()
def teacher_save_add_overwrite(
question: str, answer: str, current_id: str
) -> Tuple[str, str, str, List[List[str]], str]:
"""
Add a new manual Q&A or overwrite existing one
with the same normalized question.
"""
question = (question or "").strip()
answer = (answer or "").strip()
current_id = current_id or ""
if not question or not answer:
msg = "❌ ກະລຸນາໃສ່ທັງຄໍາຖາມແລະຄໍາຕອບ."
return question, answer, current_id, _table(), msg
norm_q = normalize_question(question)
entry = qa_store.MANUAL_QA_INDEX.get(norm_q)
if entry:
# overwrite existing manual Q&A
entry["q"] = question
entry["a"] = answer
entry["norm_q"] = norm_q
current_id = entry["id"]
msg = "✅ ອັບເດດ Q&A ທີ່ມີຢູ່ແລ້ວ."
else:
# create new entry
new_id = generate_new_manual_id()
entry = {
"id": new_id,
"q": question,
"a": answer,
"norm_q": norm_q,
}
qa_store.MANUAL_QA_LIST.append(entry)
qa_store.MANUAL_QA_INDEX[norm_q] = entry
current_id = new_id
msg = "✅ ບັນທຶກ Q&A ໃໝ່ສໍາເລັດ."
save_manual_qa_file()
rebuild_combined_qa()
return question, answer, current_id, _table(), msg
def teacher_update_current(
question: str, answer: str, current_id: str
) -> Tuple[str, str, str, List[List[str]], str]:
"""
Update the currently selected manual Q&A by id.
"""
question = (question or "").strip()
answer = (answer or "").strip()
current_id = current_id or ""
if not current_id:
msg = "❌ ກະລຸນາເລືອກ Q&A ຈາກຕາຕະລາງກ່ອນ."
return question, answer, current_id, _table(), msg
if not question or not answer:
msg = "❌ ກະລຸນາໃສ່ທັງຄໍາຖາມແລະຄໍາຕອບ."
return question, answer, current_id, _table(), msg
entry = next((e for e in qa_store.MANUAL_QA_LIST if e["id"] == current_id), None)
if not entry:
msg = "⚠️ ບໍ່ພົບ Q&A ທີ່ເລືອກ."
current_id = ""
return question, answer, current_id, _table(), msg
# remove old index
qa_store.MANUAL_QA_INDEX.pop(entry["norm_q"], None)
new_norm = normalize_question(question)
entry["q"] = question
entry["a"] = answer
entry["norm_q"] = new_norm
qa_store.MANUAL_QA_INDEX[new_norm] = entry
save_manual_qa_file()
rebuild_combined_qa()
msg = "✅ ແກ້ໄຂ Q&A ສໍາເລັດ."
return question, answer, current_id, _table(), msg
def teacher_delete_current(
current_id: str,
) -> Tuple[str, str, str, List[List[str]], str]:
"""
Delete the currently selected manual Q&A.
"""
current_id = current_id or ""
if not current_id:
msg = "❌ ກະລຸນາເລືອກ Q&A ກ່ອນຈະລຶບ."
return "", "", current_id, _table(), msg
entry = next((e for e in qa_store.MANUAL_QA_LIST if e["id"] == current_id), None)
if not entry:
msg = "⚠️ ບໍ່ພົບ Q&A ທີ່ຈະລຶບ."
return "", "", "", _table(), msg
qa_store.MANUAL_QA_LIST = [e for e in qa_store.MANUAL_QA_LIST if e["id"] != current_id]
qa_store.MANUAL_QA_INDEX.pop(entry["norm_q"], None)
save_manual_qa_file()
rebuild_combined_qa()
msg = "🗑️ ລຶບ Q&A ສໍາເລັດ."
return "", "", "", _table(), msg
def teacher_on_table_select(
evt: gr.SelectData,
) -> Tuple[str, str, str, str]:
"""
When teacher clicks a row in the Q&A table, load Q/A into textboxes.
We only use the SelectData event:
- evt.index -> (row, col)
- evt.row_value -> the whole row [id, question, answer]
"""
try:
if evt is None or evt.index is None or evt.row_value is None:
raise ValueError("Empty select event")
# row_value is already the full row (list-like)
row = list(evt.row_value)
current_id = str(row[0]) if len(row) > 0 else ""
question = str(row[1]) if len(row) > 1 else ""
answer = str(row[2]) if len(row) > 2 else ""
if not current_id:
raise ValueError("Empty ID from selected row")
msg = f"✏️ ເລືອກ Q&A ID {current_id} ສໍາລັບແກ້ໄຂ."
except Exception as e: # noqa: BLE001
print(f"[WARN] teacher_on_table_select error: {e}")
current_id = ""
question = ""
answer = ""
msg = "⚠️ ບໍ່ສາມາດເລືອກແຖວໄດ້."
return question, answer, current_id, msg