> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bedolagam.ru/llms.txt
> Use this file to discover all available pages before exploring further.

# Редактор меню

> Визуальная настройка структуры меню Cabinet через drag-and-drop

## Обзор

Редактор меню позволяет администраторам полностью настраивать структуру навигации Cabinet: расположение кнопок, количество кнопок в ряду, стили, иконки, локализованные подписи и добавление кастомных URL-кнопок. Все изменения применяются мгновенно без перезапуска.

### Возможности

* **Drag-and-drop** сортировка рядов
* Перемещение кнопок внутри ряда (вверх/вниз)
* Настройка **1–3 кнопок** на ряд
* 8 встроенных секций (home, subscription, balance, referral, support, info, admin, language)
* **Кастомные URL-кнопки** с выбором режима открытия
* Цветовые стили: `primary`, `success`, `danger`, `default`
* Кастомные emoji-иконки (Telegram Custom Emoji ID)
* Мультиязычные подписи (ru, en, ua, zh, fa)
* Включение/отключение отдельных кнопок
* Сброс к настройкам по умолчанию

> [!WARNING]
>
> Для работы редактора меню необходимо:
>
> 1. `CABINET_ENABLED=true`
> 2. `MENU_LAYOUT_ENABLED=true` в настройках бота
> 3. RBAC-разрешение `settings:edit` для редактирования, `settings:read` для просмотра

***

## Включение

```env theme={null}
MENU_LAYOUT_ENABLED=true
```

При включении структура меню управляется через редактор, а не задаётся статически в коде. Подробнее о режимах меню: [Интерфейс и брендирование → Динамическое меню](https://docs.bedolagam.ru/bot/interface-settings.md#динамическое-меню).

***

## Использование

### Открытие редактора

Cabinet → Админ-панель → **Настройки** → вкладка **Редактор меню**

### Работа с рядами

> **Перетаскивание**
>
> Захватите ряд за ручку и перетащите для изменения порядка

> **Кнопок в ряду**
>
> Выберите 1, 2 или 3 кнопки на ряд через селектор в заголовке

> **Удаление ряда**
>
> Ряды, содержащие только кастомные кнопки, можно удалить целиком

### Настройка кнопки

Нажмите на кнопку для раскрытия настроек:

| Параметр | Описание | Доступно для |
| - | - | - |
| **Стиль** | Цвет кнопки: primary (синий), success (зелёный), danger (красный), default | Все кнопки |
| **Emoji ID** | Telegram Custom Emoji ID для иконки | Все кнопки |
| **Вкл/Выкл** | Показывать или скрыть кнопку | Все кнопки |
| **Подписи** | Локализованные названия (ru, en, ua, zh, fa), макс. 100 символов | Все кнопки |
| **URL** | Ссылка для перехода (http\:// или https\://) | Только кастомные |
| **Режим открытия** | `external` (браузер) или `webapp` (Telegram WebApp) | Только кастомные |

> [!NOTE]
>
> Встроенные кнопки нельзя удалить — только отключить или переместить. Кастомные кнопки можно удалить через иконку корзины.

### Добавление кнопки

1. В нужном ряду нажмите **Добавить кнопку**
2. Выберите из списка:
   * **Встроенную секцию** — доступны только ещё не использованные
   * **URL-кнопку** — создаёт кастомную кнопку с настраиваемой ссылкой

### Сохранение и сброс

* **Сохранить** — применяет все изменения атомарно (один запрос)
* **Отменить** — возвращает к последнему сохранённому состоянию
* **Сбросить** — восстанавливает расположение по умолчанию (с подтверждением)

***

## Кастомные URL-кнопки

Кастомные кнопки позволяют добавлять внешние ссылки в меню Cabinet.

### Режим открытия (`open_in`)

| Значение | Описание | Требования |
| - | - | - |
| `external` | Открывает URL в браузере | http\:// или https\:// |
| `webapp` | Открывает URL как Telegram WebApp внутри бота | **Только** https\:// |

> [!WARNING]
>
> При выборе `webapp` URL **обязательно** должен начинаться с `https://`. HTTP-ссылки будут отклонены при сохранении.

### Примеры использования

* Ссылка на сайт проекта (`external`)
* Ссылка на FAQ или документацию (`external`)
* Встроенная веб-форма обратной связи (`webapp`)
* Внешний сервис мониторинга (`webapp`)

***

## Расположение по умолчанию

| Ряд | Кнопки | Кнопок в ряду |
| - | - | - |
| 1 | home | 1 |
| 2 | subscription, balance | 2 |
| 3 | referral, support | 2 |
| 4 | info, language | 2 |
| 5 | admin | 1 |

Встроенные секции:

| ID | Описание |
| - | - |
| `home` | Главная страница |
| `subscription` | Управление подпиской |
| `balance` | Баланс и пополнение |
| `referral` | Реферальная программа |
| `support` | Тикеты поддержки |
| `info` | Информация (FAQ, правила) |
| `admin` | Админ-панель (видна только администраторам) |
| `language` | Выбор языка |

***

## Ограничения

| Параметр | Лимит |
| - | - |
| Максимум рядов | 20 |
| Кнопок в ряду | 1–3 |
| Длина подписи | 100 символов |
| Длина Emoji ID | 100 символов |
| URL кнопки | http\:// или https\:// |
| ID кастомной кнопки | Должен начинаться с `custom_` |

***

## API эндпоинты

### GET /cabinet/admin/menu-layout

Возвращает текущую конфигурацию меню (объединяет layout и стили).

**Ответ:**

```json theme={null}
{
  "rows": [
    {
      "id": "row_1",
      "max_per_row": 1,
      "buttons": [
        {
          "id": "home",
          "type": "builtin",
          "style": "primary",
          "icon_custom_emoji_id": "5368324343330516923",
          "enabled": true,
          "labels": {"ru": "Главная", "en": "Home"},
          "url": null,
          "open_in": "external"
        }
      ]
    },
    {
      "id": "row_custom_1",
      "max_per_row": 2,
      "buttons": [
        {
          "id": "custom_12345",
          "type": "custom",
          "style": "success",
          "icon_custom_emoji_id": "",
          "enabled": true,
          "labels": {"ru": "Наш сайт", "en": "Our Website"},
          "url": "https://example.com",
          "open_in": "external"
        }
      ]
    }
  ]
}
```

### PUT /cabinet/admin/menu-layout

Сохранение полной конфигурации. Тело запроса — тот же формат, что и ответ GET.

Сервер атомарно обновляет две системные настройки:

* `CABINET_MENU_LAYOUT` — расположение рядов и кастомные кнопки
* `CABINET_BUTTON_STYLES` — стили встроенных секций

### POST /cabinet/admin/menu-layout/reset

Сброс к расположению по умолчанию. Требует подтверждения на фронтенде.

***

## Кэширование

Конфигурация меню кэшируется в памяти для быстрого доступа:

* **Загрузка** — при старте бота (`load_menu_layout_cache()`, `load_button_styles_cache()`)
* **Обновление** — автоматически после каждого сохранения через API
* **Формат** — deep copy из кэша для защиты от мутаций

Если кэш не загружен, используются значения по умолчанию.

***

## Устранение проблем

### Вкладка редактора не отображается

1. `MENU_LAYOUT_ENABLED=true`?
2. У пользователя есть RBAC-разрешение `settings:read`?
3. Пользователь является администратором (`ADMIN_IDS` или `ADMIN_EMAILS`)?

### Кнопка webapp не работает

1. URL начинается с `https://`? HTTP не поддерживается для webapp-режима
2. Сайт по URL доступен и не блокирует iframe?
3. Telegram WebApp поддерживает URL? (некоторые домены могут быть заблокированы)

### Изменения не применяются

1. Нажали **Сохранить** после внесения изменений?
2. Проверьте логи бота на ошибки валидации:
   ```bash theme={null}
   docker logs <bot_container> 2>&1 | grep -i "menu_layout"
   ```
3. Попробуйте **Сбросить** и настроить заново


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.