210 lines
6.9 KiB
Python
210 lines
6.9 KiB
Python
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()
|
||
)
|