Bot & Automation

jorgasisten

/root/hermes-projects/jorgasisten

apps/jorgasisten/bot/keyboards.py text
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup

from jorgasisten.services.spreadsheet_registry import SpreadsheetEntry

BTN_CHAT_UMUM = "💬 Chat Umum"
BTN_TANYA_DATA = "🔍 Cari Data"
BTN_TAMBAH_DATA = "➕ Tambah Data"
BTN_UPDATE_DATA = "✏️ Update Data"
BTN_HAPUS_DATA = "🗑️ Hapus Data"
BTN_RINGKASAN = "📊 Ringkasan"
BTN_SHEET_TOOLS = "📋 Sheet/Tabel"
BTN_SPREADSHEETS = "📄 Spreadsheet"
BTN_SETTINGS = "⚙️ Settings"
BTN_MANAGE_SHEETS = "🗂️ Kelola Sheet"

BTN_LIHAT_SHEET = "📄 Lihat Sheet"
BTN_BUAT_SHEET = "➕ Buat Sheet Baru"
BTN_GANTI_HEADER = "🧱 Ganti Header/Kolom"
BTN_RENAME_SHEET = "✏️ Rename Sheet"
BTN_HAPUS_SHEET = "🗑️ Hapus Sheet"
BTN_KEMBALI = "⬅️ Kembali"

BTN_SPREADSHEET_ACTIVE = "📍 Spreadsheet Aktif"
BTN_SPREADSHEET_LIST = "📚 Daftar Spreadsheet"
BTN_SPREADSHEET_ADD = "➕ Tambah Spreadsheet"
BTN_SPREADSHEET_SELECT = "🎯 Ganti Spreadsheet Aktif"
BTN_SPREADSHEET_DEFAULT = "⭐ Set Default Spreadsheet"
BTN_SPREADSHEET_DELETE = "🗑️ Hapus Spreadsheet"

CALLBACK_CONFIRM_YES = "confirm:yes"
CALLBACK_CONFIRM_NO = "confirm:no"
CALLBACK_CONFIRM_EDIT = "confirm:edit"
CALLBACK_RESULT_REFRESH = "result:refresh"
CALLBACK_RESULT_DETAIL = "result:detail"
CALLBACK_RESULT_EDIT = "result:edit"
CALLBACK_RESULT_DELETE = "result:delete"
CALLBACK_RESULT_SUMMARY = "result:summary"
CALLBACK_RESULT_DOWNLOAD_PDF = "result:download_pdf"
CALLBACK_RESULT_DOWNLOAD_EXCEL = "result:download_excel"
CALLBACK_SPREADSHEET_SELECT_PREFIX = "spreadsheet:select:"
CALLBACK_SPREADSHEET_DEFAULT_PREFIX = "spreadsheet:default:"
CALLBACK_SHEET_ACTION_PREFIX = "sheetaction:"
CALLBACK_SPREADSHEET_MENU_ACTIVE = "spreadsheetmenu:active"
CALLBACK_SPREADSHEET_MENU_LIST = "spreadsheetmenu:list"
CALLBACK_SPREADSHEET_MENU_ADD = "spreadsheetmenu:add"
CALLBACK_SPREADSHEET_MENU_SELECT = "spreadsheetmenu:select"
CALLBACK_SPREADSHEET_MENU_DEFAULT = "spreadsheetmenu:default"
CALLBACK_SPREADSHEET_MENU_DELETE = "spreadsheetmenu:delete"
CALLBACK_SPREADSHEET_DELETE_PREFIX = "spreadsheet:delete:"
CALLBACK_HOME_MENU_CHAT = "homemenu:chat"
CALLBACK_HOME_MENU_QUERY = "homemenu:query"
CALLBACK_HOME_MENU_ADD = "homemenu:add"
CALLBACK_HOME_MENU_UPDATE = "homemenu:update"
CALLBACK_HOME_MENU_DELETE = "homemenu:delete"
CALLBACK_HOME_MENU_SUMMARY = "homemenu:summary"
CALLBACK_HOME_MENU_SHEETS = "homemenu:sheets"
CALLBACK_HOME_MENU_SPREADSHEETS = "homemenu:spreadsheets"
CALLBACK_HOME_MENU_MANAGE = "homemenu:manage"
CALLBACK_SHEET_MENU_LIST = "sheetmenu:list"
CALLBACK_SHEET_MENU_CREATE = "sheetmenu:create"
CALLBACK_SHEET_MENU_HEADERS = "sheetmenu:headers"
CALLBACK_SHEET_MENU_RENAME = "sheetmenu:rename"
CALLBACK_SHEET_MENU_DELETE = "sheetmenu:delete"
CALLBACK_MANAGE_MENU_OPEN = "managemenu:open"
CALLBACK_MANAGE_MENU_SPREADSHEETS = "managemenu:spreadsheets"
CALLBACK_MANAGE_MENU_SHEETS = "managemenu:sheets"
CALLBACK_SETTINGS_MENU_OPEN = "settingsmenu:open"
CALLBACK_SETTINGS_MENU_ACTIVE = "settingsmenu:active"
CALLBACK_SETTINGS_MENU_SELECT = "settingsmenu:select"
CALLBACK_SETTINGS_MENU_LIST = "settingsmenu:list"
CALLBACK_SETTINGS_MENU_STATUS = "settingsmenu:status"
CALLBACK_SETTINGS_MENU_CLEAR = "settingsmenu:clear"


def main_menu_keyboard() -> ReplyKeyboardMarkup:
    return main_menu_keyboard_for_role("admin")


def main_menu_keyboard_for_role(role: str) -> ReplyKeyboardMarkup:
    if role == "viewer":
        keyboard = [
            [KeyboardButton(text=BTN_TANYA_DATA), KeyboardButton(text=BTN_RINGKASAN)],
            [KeyboardButton(text=BTN_LIHAT_SHEET)],
        ]
    else:
        keyboard = [
            [KeyboardButton(text=BTN_TAMBAH_DATA), KeyboardButton(text=BTN_UPDATE_DATA)],
            [KeyboardButton(text=BTN_HAPUS_DATA), KeyboardButton(text=BTN_RINGKASAN)],
            [KeyboardButton(text=BTN_MANAGE_SHEETS)],
        ]

    return ReplyKeyboardMarkup(
        keyboard=keyboard,
        resize_keyboard=True,
        input_field_placeholder="Langsung chat atau pilih shortcut...",
    )


def sheet_tools_keyboard() -> ReplyKeyboardMarkup:
    return ReplyKeyboardMarkup(
        keyboard=[
            [KeyboardButton(text=BTN_LIHAT_SHEET)],
            [KeyboardButton(text=BTN_BUAT_SHEET)],
            [KeyboardButton(text=BTN_GANTI_HEADER)],
            [KeyboardButton(text=BTN_RENAME_SHEET)],
            [KeyboardButton(text=BTN_HAPUS_SHEET)],
            [KeyboardButton(text=BTN_KEMBALI)],
        ],
        resize_keyboard=True,
        input_field_placeholder="Pilih tool sheet atau tulis instruksi...",
    )


def spreadsheet_tools_keyboard() -> ReplyKeyboardMarkup:
    return ReplyKeyboardMarkup(
        keyboard=[
            [KeyboardButton(text=BTN_SPREADSHEET_ACTIVE), KeyboardButton(text=BTN_SPREADSHEET_LIST)],
            [KeyboardButton(text=BTN_SPREADSHEET_ADD), KeyboardButton(text=BTN_SPREADSHEET_SELECT)],
            [KeyboardButton(text=BTN_SPREADSHEET_DEFAULT)],
            [KeyboardButton(text=BTN_SPREADSHEET_DELETE)],
            [KeyboardButton(text=BTN_KEMBALI)],
        ],
        resize_keyboard=True,
        input_field_placeholder="Atur spreadsheet atau tulis instruksi...",
    )


def manage_sheets_keyboard() -> ReplyKeyboardMarkup:
    return ReplyKeyboardMarkup(
        keyboard=[
            [KeyboardButton(text=BTN_SPREADSHEETS)],
            [KeyboardButton(text=BTN_SHEET_TOOLS)],
            [KeyboardButton(text=BTN_KEMBALI)],
        ],
        resize_keyboard=True,
        input_field_placeholder="Pilih Spreadsheet atau Sheet/Tabel...",
    )


def confirmation_keyboard() -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(text="✅ Ya, lanjut", callback_data=CALLBACK_CONFIRM_YES),
                InlineKeyboardButton(text="✖️ Batal", callback_data=CALLBACK_CONFIRM_NO),
            ]
        ]
    )


def result_actions_keyboard(*, has_single_row: bool = False) -> InlineKeyboardMarkup:
    detail_row = [InlineKeyboardButton(text="🔄 Refresh", callback_data=CALLBACK_RESULT_REFRESH)]
    if has_single_row:
        detail_row.append(InlineKeyboardButton(text="📋 Detail", callback_data=CALLBACK_RESULT_DETAIL))

    action_rows = [detail_row]
    if has_single_row:
        action_rows.append(
            [
                InlineKeyboardButton(text="✏️ Edit", callback_data=CALLBACK_RESULT_EDIT),
                InlineKeyboardButton(text="🗑️ Hapus", callback_data=CALLBACK_RESULT_DELETE),
            ]
        )
    action_rows.append([InlineKeyboardButton(text="📊 Ringkas Sheet Ini", callback_data=CALLBACK_RESULT_SUMMARY)])
    action_rows.append(
        [
            InlineKeyboardButton(text="📥 PDF", callback_data=CALLBACK_RESULT_DOWNLOAD_PDF),
            InlineKeyboardButton(text="📥 Excel", callback_data=CALLBACK_RESULT_DOWNLOAD_EXCEL),
        ]
    )
    return InlineKeyboardMarkup(inline_keyboard=action_rows)


def summary_download_keyboard() -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(text="📥 Download PDF", callback_data=CALLBACK_RESULT_DOWNLOAD_PDF),
                InlineKeyboardButton(text="📥 Download Excel", callback_data=CALLBACK_RESULT_DOWNLOAD_EXCEL),
            ]
        ]
    )


def spreadsheet_select_keyboard(
    entries: list[SpreadsheetEntry],
    *,
    active_key: str = "",
    default_key: str = "",
    mode: str = "select",
) -> InlineKeyboardMarkup:
    inline_keyboard: list[list[InlineKeyboardButton]] = []
    callback_prefix = CALLBACK_SPREADSHEET_SELECT_PREFIX if mode == "select" else CALLBACK_SPREADSHEET_DEFAULT_PREFIX
    for entry in entries:
        label = entry.name
        if entry.key == active_key:
            label = f"[Aktif] {label}"
        if entry.key == default_key:
            label = f"[Default] {label}"
        inline_keyboard.append(
            [
                InlineKeyboardButton(
                    text=label[:64],
                    callback_data=f"{callback_prefix}{entry.key}",
                )
            ]
        )
    return InlineKeyboardMarkup(inline_keyboard=inline_keyboard)


def sheet_action_keyboard(sheet_titles: list[str], *, action: str) -> InlineKeyboardMarkup:
    inline_keyboard: list[list[InlineKeyboardButton]] = []
    for index, title in enumerate(sheet_titles):
        inline_keyboard.append(
            [
                InlineKeyboardButton(
                    text=title[:64],
                    callback_data=f"{CALLBACK_SHEET_ACTION_PREFIX}{action}:{index}",
                )
            ]
        )
    return InlineKeyboardMarkup(inline_keyboard=inline_keyboard)


def spreadsheet_tools_inline_keyboard(*, can_set_default: bool = True) -> InlineKeyboardMarkup:
    inline_keyboard = [
        [
            InlineKeyboardButton(text="📍 Spreadsheet Aktif", callback_data=CALLBACK_SPREADSHEET_MENU_ACTIVE),
            InlineKeyboardButton(text="📚 Daftar", callback_data=CALLBACK_SPREADSHEET_MENU_LIST),
        ],
        [
            InlineKeyboardButton(text="➕ Tambah", callback_data=CALLBACK_SPREADSHEET_MENU_ADD),
            InlineKeyboardButton(text="🎯 Pilih", callback_data=CALLBACK_SPREADSHEET_MENU_SELECT),
        ],
    ]
    if can_set_default:
        inline_keyboard.append(
            [InlineKeyboardButton(text="⭐ Set Default", callback_data=CALLBACK_SPREADSHEET_MENU_DEFAULT)]
        )
    inline_keyboard.append(
        [InlineKeyboardButton(text="🗑️ Hapus Spreadsheet", callback_data=CALLBACK_SPREADSHEET_MENU_DELETE)]
    )
    return InlineKeyboardMarkup(inline_keyboard=inline_keyboard)


def home_menu_inline_keyboard() -> InlineKeyboardMarkup:
    return home_menu_inline_keyboard_for_role("admin")


def home_menu_inline_keyboard_for_role(role: str) -> InlineKeyboardMarkup:
    if role == "viewer":
        inline_keyboard = [
            [
                InlineKeyboardButton(text="🔍 Cari Data", callback_data=CALLBACK_HOME_MENU_QUERY),
                InlineKeyboardButton(text="📊 Ringkasan", callback_data=CALLBACK_HOME_MENU_SUMMARY),
            ],
            [InlineKeyboardButton(text="📄 Lihat Sheet", callback_data=CALLBACK_SHEET_MENU_LIST)],
        ]
    else:
        inline_keyboard = [
            [
                InlineKeyboardButton(text="➕ Tambah Data", callback_data=CALLBACK_HOME_MENU_ADD),
                InlineKeyboardButton(text="✏️ Update Data", callback_data=CALLBACK_HOME_MENU_UPDATE),
            ],
            [
                InlineKeyboardButton(text="🗑️ Hapus Data", callback_data=CALLBACK_HOME_MENU_DELETE),
                InlineKeyboardButton(text="📊 Ringkasan", callback_data=CALLBACK_HOME_MENU_SUMMARY),
            ],
            [
                InlineKeyboardButton(text="🔍 Cari Data", callback_data=CALLBACK_HOME_MENU_QUERY),
                InlineKeyboardButton(text="🗂️ Kelola Sheet", callback_data=CALLBACK_HOME_MENU_MANAGE),
            ],
        ]
    return InlineKeyboardMarkup(inline_keyboard=inline_keyboard)


def manage_sheets_inline_keyboard() -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(
        inline_keyboard=[
            [InlineKeyboardButton(text="📄 Spreadsheet", callback_data=CALLBACK_MANAGE_MENU_SPREADSHEETS)],
            [InlineKeyboardButton(text="📋 Sheet/Tabel", callback_data=CALLBACK_MANAGE_MENU_SHEETS)],
        ]
    )


def sheet_tools_inline_keyboard() -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(text="📄 Lihat Sheet", callback_data=CALLBACK_SHEET_MENU_LIST),
                InlineKeyboardButton(text="➕ Buat Sheet", callback_data=CALLBACK_SHEET_MENU_CREATE),
            ],
            [
                InlineKeyboardButton(text="🧱 Ganti Header", callback_data=CALLBACK_SHEET_MENU_HEADERS),
                InlineKeyboardButton(text="✏️ Rename", callback_data=CALLBACK_SHEET_MENU_RENAME),
            ],
            [InlineKeyboardButton(text="🗑️ Hapus Sheet", callback_data=CALLBACK_SHEET_MENU_DELETE)],
        ]
    )


def settings_inline_keyboard() -> InlineKeyboardMarkup:
    return settings_inline_keyboard_for_role("admin")


def settings_inline_keyboard_for_role(role: str) -> InlineKeyboardMarkup:
    if role in {"admin", "operator"}:
        inline_keyboard = [
            [
                InlineKeyboardButton(text="📍 Spreadsheet Aktif", callback_data=CALLBACK_SETTINGS_MENU_ACTIVE),
                InlineKeyboardButton(text="📡 Status Bot", callback_data=CALLBACK_SETTINGS_MENU_STATUS),
            ],
            [
                InlineKeyboardButton(text="🎯 Pilih Spreadsheet", callback_data=CALLBACK_SETTINGS_MENU_SELECT),
                InlineKeyboardButton(text="📚 Daftar Spreadsheet", callback_data=CALLBACK_SETTINGS_MENU_LIST),
            ],
            [
                InlineKeyboardButton(text="🗑️ Hapus Spreadsheet", callback_data=CALLBACK_SPREADSHEET_MENU_DELETE),
                InlineKeyboardButton(text="🧹 Bersihkan Chat", callback_data=CALLBACK_SETTINGS_MENU_CLEAR),
            ],
        ]
    else:
        inline_keyboard = [
            [InlineKeyboardButton(text="📡 Status Bot", callback_data=CALLBACK_SETTINGS_MENU_STATUS)],
            [InlineKeyboardButton(text="🧹 Bersihkan Chat", callback_data=CALLBACK_SETTINGS_MENU_CLEAR)],
        ]
    return InlineKeyboardMarkup(inline_keyboard=inline_keyboard)


def create_review_keyboard() -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(text="✅ Simpan", callback_data=CALLBACK_CONFIRM_YES),
                InlineKeyboardButton(text="✏️ Edit", callback_data=CALLBACK_CONFIRM_EDIT),
                InlineKeyboardButton(text="✖️ Batal", callback_data=CALLBACK_CONFIRM_NO),
            ]
        ]
    )


def spreadsheet_delete_keyboard(
    entries: list[SpreadsheetEntry],
    *,
    active_key: str = "",
    default_key: str = "",
) -> InlineKeyboardMarkup:
    inline_keyboard: list[list[InlineKeyboardButton]] = []
    for entry in entries:
        label = entry.name
        if entry.key == active_key:
            label = f"[Aktif] {label}"
        if entry.key == default_key:
            label = f"[Default] {label}"
        inline_keyboard.append(
            [
                InlineKeyboardButton(
                    text=label[:64],
                    callback_data=f"{CALLBACK_SPREADSHEET_DELETE_PREFIX}{entry.key}",
                )
            ]
        )
    return InlineKeyboardMarkup(inline_keyboard=inline_keyboard)