tasks: add pagination with inline navigation buttons

parent ed2b2913
......@@ -2,6 +2,31 @@ from telegrinder import InlineKeyboard, InlineButton
from config import TASK_URL
def tasks_nav_kb(maintainer: str, branch: str, offset: int, total: int, per_page: int = 10):
kb = InlineKeyboard()
nav_buttons = []
if offset > 0:
nav_buttons.append(InlineButton(
text="← Назад",
callback_data=f"tasks/{maintainer}/{branch}/{offset - per_page}",
))
if offset + per_page < total:
nav_buttons.append(InlineButton(
text="Вперёд →",
callback_data=f"tasks/{maintainer}/{branch}/{offset + per_page}",
))
if nav_buttons:
for btn in nav_buttons:
kb.add(btn)
kb.row()
return kb.get_markup()
def task_page_kb(task: int):
kb = InlineKeyboard()
kb.add(
......
from telegrinder import Dispatch, Message
from telegrinder.rules import Command, Argument
from telegrinder import Dispatch, Message, CallbackQuery
from telegrinder.rules import Command, Argument, CallbackDataMarkup
from telegrinder.tools.formatting import HTMLFormatter, code_inline
......@@ -14,9 +14,26 @@ from data.keyboards import tasks_keyboards
from config import TASK_URL, DEFAUIL_BRANCHES
PER_PAGE = 20
dp = Dispatch()
async def format_task_entry(task) -> str:
build_time = await date_format(task.task_changed)
subtasks = len(task.subtasks)
return HTMLFormatter(f"<a href='{TASK_URL}{task.task_id}'>{task.task_id}</a>") + \
f" | {task.task_repo} | {task.task_state} | {build_time} | {subtasks} | {task.task_message}\n"
async def format_tasks_page(tasks, offset: int, total: int) -> str:
message = _bold("Таски:\n\n")
for task in tasks:
message += await format_task_entry(task)
message += f"\nТаски {offset + 1}–{offset + len(tasks)} из {total}"
return message
@dp.message(Command("tasks", Argument("maintainer", optional=True), Argument("branch", optional=True)))
async def tasks_handler(m: Message, user: User | None, maintainer: str | None = None, branch: str | None = None) -> None:
......@@ -25,17 +42,17 @@ async def tasks_handler(m: Message, user: User | None, maintainer: str | None =
return await m.answer("Репозиторий не найден.")
if maintainer:
maintainer = DB.maintainer.get(maintainer.lower())
if not maintainer:
maintainer_obj = DB.maintainer.get(maintainer.lower())
if not maintainer_obj:
return await m.answer("Сопровождающий не найден.")
elif user:
maintainer = user.maintainer
maintainer_obj = user.maintainer
else:
return
try:
tasks_data = await altrepo.api.task.progress.find_tasks(
input=[f"@{maintainer.nickname}"], branch=branch
input=[f"@{maintainer_obj.nickname}"], branch=branch
)
except DataNotFoundError:
return await m.answer("Таски не найдены.")
......@@ -44,7 +61,40 @@ async def tasks_handler(m: Message, user: User | None, maintainer: str | None =
if not tasks:
return await m.answer("Нет тасков.")
await m.answer(await create_tasks_message(tasks))
total = len(tasks)
page = tasks[:PER_PAGE]
await m.answer(
await format_tasks_page(page, 0, total),
reply_markup=tasks_keyboards.tasks_nav_kb(maintainer_obj.nickname, branch, 0, total, PER_PAGE),
)
@dp.callback_query(CallbackDataMarkup("tasks/<maintainer>/<branch>/<offset:int>"))
async def tasks_page_handler(
cb: CallbackQuery, maintainer: str, branch: str, offset: int,
) -> None:
try:
tasks_data = await altrepo.api.task.progress.find_tasks(
input=[f"@{maintainer}"], branch=branch
)
except DataNotFoundError:
await cb.answer("Таски не найдены.")
return
tasks = [task for task in tasks_data.tasks if task.task_state != "DONE"]
if not tasks:
await cb.answer("Нет тасков.")
return
total = len(tasks)
page = tasks[offset:offset + PER_PAGE]
await cb.edit_text(
await format_tasks_page(page, offset, total),
reply_markup=tasks_keyboards.tasks_nav_kb(maintainer, branch, offset, total, PER_PAGE),
)
await cb.answer()
@dp.message(Command("task_search", Argument("args", optional=True)))
......@@ -60,8 +110,11 @@ async def task_search_handler(m: Message, args: str | None = None) -> None:
if not tasks_data.tasks:
return await m.answer("Нет тасков.")
msg = await create_tasks_message(tasks_data.tasks)
answer = (await m.answer(msg)).unwrap_or_none()
msg = ""
for task in tasks_data.tasks:
msg += await format_task_entry(task)
answer = (await m.answer(_bold("Таски:\n\n") + msg)).unwrap_or_none()
if answer is None:
await m.answer("Слишком много результатов, уточните поиск.")
......@@ -130,14 +183,3 @@ async def task_handler(m: Message, user: User | None, task: int | None = None) -
task_message.append("\n".join(subtask_lines))
await m.answer("\n".join(task_message), reply_markup=markup)
async def create_tasks_message(tasks) -> str:
tasks_message = _bold("Таски:\n\n")
for task in tasks:
build_time = await date_format(task.task_changed)
subtasks = len(task.subtasks)
tasks_message += HTMLFormatter(f"<a href='{TASK_URL}{task.task_id}'>{task.task_id}</a>") + \
f" | {task.task_repo} | {task.task_state} | {build_time} | {subtasks} | {task.task_message}\n"
return tasks_message
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment