intra_max_chatbot/bot/keyboards.py
2026-04-03 00:30:24 +03:00

210 lines
6.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from maxapi.types.attachments.attachment import Attachment
from maxapi.types.attachments.buttons import (
CallbackButton,
RequestContactButton,
)
from maxapi.utils.inline_keyboard import InlineKeyboardBuilder
from bot.flow_config import PAYLOADS
from bot.texts import Btn
def main_menu_kb() -> Attachment:
return (
InlineKeyboardBuilder()
.row(
CallbackButton(text=Btn.CREATE_TICKET, payload=PAYLOADS.CREATE_TICKET),
CallbackButton(text=Btn.VIEW_TICKETS, payload=PAYLOADS.VIEW_TICKETS),
)
.as_markup()
)
def contact_request_kb() -> Attachment:
return (
InlineKeyboardBuilder()
.row(RequestContactButton(text=Btn.SHARE_CONTACT))
.as_markup()
)
def confirm_ticket_kb() -> Attachment:
"""Клавиатура подтверждения создания заявки."""
return (
InlineKeyboardBuilder()
.row(CallbackButton(text=Btn.CONFIRM_TICKET, payload=PAYLOADS.CONFIRM_TICKET))
.row(
CallbackButton(text=Btn.EDIT_TICKET, payload=PAYLOADS.EDIT_TICKET),
CallbackButton(text=Btn.CANCEL_TICKET, payload=PAYLOADS.CANCEL_TICKET),
)
.as_markup()
)
def menu_only_kb() -> Attachment:
"""Клавиатура с единственной кнопкой возврата в главное меню."""
return (
InlineKeyboardBuilder()
.row(CallbackButton(text=Btn.MAIN_MENU, payload=PAYLOADS.MAIN_MENU))
.as_markup()
)
def done_ticket_kb() -> Attachment:
return (
InlineKeyboardBuilder()
.row(
CallbackButton(text=Btn.DONE_TICKET, payload=PAYLOADS.DONE_TICKET),
CallbackButton(text=Btn.CANCEL_TICKET, payload=PAYLOADS.CANCEL_TICKET),
)
.as_markup()
)
def tickets_list_kb(
tickets: list[dict], page: int, total: int, page_size: int = 8
) -> Attachment:
builder = InlineKeyboardBuilder()
for t in tickets:
desc_preview = (t["description"] or "")[:35]
if len(t["description"] or "") > 35:
desc_preview += ""
status_icon = {"open": "🔴", "in_progress": "🟡", "closed": "🟢"}.get(
t["status"], ""
)
builder.row(
CallbackButton(
text=f"#{t['id']} {status_icon} {desc_preview}",
payload=PAYLOADS.TICKET_DETAIL.format(id=t["id"]),
)
)
nav = []
if page > 0:
nav.append(CallbackButton(text=Btn.PREV_PAGE, payload=PAYLOADS.TICKETS_PAGE.format(page=page - 1)))
if (page + 1) * page_size < total:
nav.append(CallbackButton(text=Btn.NEXT_PAGE, payload=PAYLOADS.TICKETS_PAGE.format(page=page + 1)))
if nav:
builder.row(*nav)
builder.row(CallbackButton(text=Btn.MAIN_MENU, payload=PAYLOADS.MAIN_MENU))
return builder.as_markup()
def intradesk_tasks_list_kb(
tasks: list[dict], page: int, total: int, page_size: int = 8
) -> Attachment:
builder = InlineKeyboardBuilder()
for t in tasks:
name_preview = (t.get("name") or "")[:35]
if len(t.get("name") or "") > 35:
name_preview += ""
sn = (t.get("status_name") or "").lower()
if "выполнен" in sn:
icon = "🟢"
elif "работ" in sn:
icon = "🟡"
elif "открыт" in sn:
icon = "🔴"
else:
icon = ""
label = t.get("task_number") or t["id"]
builder.row(
CallbackButton(
text=f"#{label} {icon} {name_preview}",
payload=PAYLOADS.ITICKET_DETAIL.format(id=t["id"]),
)
)
nav = []
if page > 0:
nav.append(CallbackButton(text=Btn.PREV_PAGE, payload=PAYLOADS.ITICKETS_PAGE.format(page=page - 1)))
if (page + 1) * page_size < total:
nav.append(CallbackButton(text=Btn.NEXT_PAGE, payload=PAYLOADS.ITICKETS_PAGE.format(page=page + 1)))
if nav:
builder.row(*nav)
builder.row(CallbackButton(text=Btn.BACK_TO_MENU, payload=PAYLOADS.MAIN_MENU))
return builder.as_markup()
def iticket_detail_kb(task_id: int | None = None, can_close: bool = False) -> Attachment:
"""Клавиатура внутри карточки Intradesk-задачи."""
builder = InlineKeyboardBuilder()
action_row = []
if task_id is not None:
action_row.append(CallbackButton(
text=Btn.ADD_COMMENT,
payload=PAYLOADS.ITICKET_COMMENT.format(task_id=task_id),
))
if task_id is not None and can_close:
action_row.append(CallbackButton(
text=Btn.CLOSE_TICKET,
payload=PAYLOADS.ITICKET_CLOSE.format(task_id=task_id),
))
if action_row:
builder.row(*action_row)
builder.row(
CallbackButton(text=Btn.BACK_TO_LIST, payload=PAYLOADS.ITICKETS_PAGE.format(page=0)),
CallbackButton(text=Btn.MAIN_MENU, payload=PAYLOADS.MAIN_MENU),
)
return builder.as_markup()
def comment_input_kb(task_id: int) -> Attachment:
"""Клавиатура при вводе комментария — кнопка назад и меню."""
return (
InlineKeyboardBuilder()
.row(
CallbackButton(
text=Btn.BACK_TO_TICKET,
payload=PAYLOADS.ITICKET_DETAIL.format(id=task_id),
),
CallbackButton(text=Btn.MAIN_MENU, payload=PAYLOADS.MAIN_MENU),
)
.as_markup()
)
def notification_kb(task_id: int, task_number: int | None = None) -> Attachment:
"""Клавиатура под уведомлением о новом комментарии."""
return (
InlineKeyboardBuilder()
.row(
CallbackButton(
text=Btn.REPLY_TO_TICKET,
payload=PAYLOADS.ITICKET_COMMENT.format(task_id=task_id),
),
CallbackButton(
text=Btn.OPEN_TICKET,
payload=PAYLOADS.ITICKET_DETAIL.format(id=task_id),
),
)
.row(CallbackButton(text=Btn.MAIN_MENU, payload=PAYLOADS.MAIN_MENU))
.as_markup()
)
def reply_confirm_kb(task_id: int) -> Attachment:
"""Клавиатура подтверждения быстрого ответа на заявку."""
return (
InlineKeyboardBuilder()
.row(
CallbackButton(
text=Btn.CONFIRM_REPLY,
payload=PAYLOADS.CONFIRM_REPLY.format(task_id=task_id),
),
CallbackButton(text=Btn.CANCEL_REPLY, payload=PAYLOADS.CANCEL_REPLY),
)
.row(CallbackButton(text=Btn.CHOOSE_TICKET, payload=PAYLOADS.VIEW_TICKETS))
.as_markup()
)
def ticket_detail_kb(page: int = 0) -> Attachment:
return (
InlineKeyboardBuilder()
.row(CallbackButton(text=Btn.BACK_TO_TICKETS, payload=PAYLOADS.TICKETS_PAGE.format(page=page)))
.row(CallbackButton(text=Btn.MAIN_MENU, payload=PAYLOADS.MAIN_MENU))
.as_markup()
)