This commit is contained in:
Artem Tsyrulnikov
2026-01-09 13:11:32 +03:00
parent 9fbb6fdbbf
commit a0b12dbcca
10 changed files with 257 additions and 119 deletions

View File

@@ -6,55 +6,74 @@ import (
"strings"
"example.com/m/bot"
"example.com/m/ui"
"github.com/NicoNex/echotron/v3"
"github.com/rs/zerolog/log"
)
type SelectWorkspace struct {
ChannelID string
BackState bot.State
ChannelID string
BackState bot.State
CurrentPage int
}
func (s *SelectWorkspace) Enter(b *bot.Bot, mode bot.RenderMode) {
// JWT уже создан в Bot.Update(), просто берем из сессии
jwt := b.Session.JWT
if jwt == "" {
log.Error().Msg("JWT is empty in session")
b.SendNew("❌ Ошибка авторизации. Попробуйте /start", Keyboard())
return
}
const msgChooseWorkspace = `
📁 Выбор workspace для канала
В какой workspace добавить канал?
`
workspaces, err := b.Backend.GetWorkspaces(context.Background(), jwt)
const msgSuccessChooseWorkspace = `
✅ Канал успешно добавлен!
📊 Проект ID: %s
📝 Название: %s
🏷 Статус: %s
`
func (s *SelectWorkspace) Enter(b *bot.Bot, mode bot.RenderMode) {
workspaces, err := b.Backend.GetWorkspaces(context.Background(), b.Session.JWT)
if err != nil {
log.Error().Err(err).Msg("Failed to get workspaces")
b.SendNew("❌ Не удалось загрузить список workspace'ов", Keyboard())
return
}
if len(workspaces) == 0 {
b.SendNew("У вас пока нет workspace'ов", Keyboard(
Row(Button("🏠 Главное меню", "back")),
))
kb := Keyboard(Row(Button("Главное меню", "back")))
b.SendNew("У вас пока нет workspace'ов", kb)
return
}
text := "📁 Выбор workspace для канала\n\n"
text += "В какой workspace добавить канал?"
// Создаем кнопки для всех workspace'ов
var allButtons []echotron.InlineKeyboardButton
for _, ws := range workspaces {
allButtons = append(allButtons, Button(ws.Name, fmt.Sprintf("select_workspace:%s", ws.ID)))
}
// Используем компонент пагинации для автоматической раскладки
const workspacesPerPage = 6
var buttons [][]echotron.InlineKeyboardButton
// Создаем кнопки для каждого workspace
for _, ws := range workspaces {
buttons = append(buttons, Row(
Button(ws.Name, fmt.Sprintf("select_workspace:%s", ws.ID)),
))
// Раскладываем workspace'ы в grid (2 в ряд) с пагинацией
elementRows := ui.BuildElementRows(ui.ElementLayoutConfig{
CurrentPage: s.CurrentPage,
ItemsPerPage: workspacesPerPage,
ItemsPerRow: 2,
}, allButtons)
buttons = append(buttons, elementRows...)
// Добавляем навигацию (стрелки появятся только если страниц > 1)
if navRow := ui.BuildNavigationRow(ui.PaginationConfig{
CurrentPage: s.CurrentPage,
TotalItems: len(allButtons),
ItemsPerPage: workspacesPerPage,
}); navRow != nil {
buttons = append(buttons, navRow)
}
// Кнопка отмены
buttons = append(buttons, Row(Button("Отмена", "cancel")))
buttons = append(buttons, Row(Button("Отмена", "cancel")))
keyboard := Keyboard(buttons...)
b.Render(text, keyboard, mode)
kb := Keyboard(buttons...)
b.Render(msgChooseWorkspace, kb, mode)
}
func (s *SelectWorkspace) HandleCallback(b *bot.Bot, u *echotron.Update) {
@@ -65,13 +84,22 @@ func (s *SelectWorkspace) HandleCallback(b *bot.Bot, u *echotron.Update) {
data := u.CallbackQuery.Data
switch {
case data == "prev":
if s.CurrentPage > 0 {
s.CurrentPage--
}
s.Enter(b, bot.EditMessage)
case data == "next":
s.CurrentPage++
s.Enter(b, bot.EditMessage)
case data == "cancel", data == "back":
if s.BackState != nil {
b.SetState(s.BackState, bot.NewMessage)
}
case strings.HasPrefix(data, "select_workspace:"):
// Извлекаем workspace_id
parts := strings.Split(data, ":")
if len(parts) != 2 {
log.Error().Str("callback_data", data).Msg("Invalid callback data format")
@@ -80,10 +108,6 @@ func (s *SelectWorkspace) HandleCallback(b *bot.Bot, u *echotron.Update) {
workspaceID := parts[1]
// Показываем индикатор загрузки
b.Edit("⏳ Добавляем канал в workspace...", Keyboard())
// Вызываем API для привязки канала к workspace
project, err := b.Backend.AttachChannelToWorkspace(
context.Background(),
s.ChannelID,
@@ -91,27 +115,19 @@ func (s *SelectWorkspace) HandleCallback(b *bot.Bot, u *echotron.Update) {
b.ChatID,
)
if err != nil {
log.Error().Err(err).Str("channel_id", s.ChannelID).Str("workspace_id", workspaceID).Msg("Failed to attach channel to workspace")
b.Edit("❌ Не удалось добавить канал в workspace", Keyboard(
Row(Button("← Назад", "back_to_select")),
))
return
}
// Показываем успешное сообщение
successText := fmt.Sprintf("✅ Канал успешно добавлен!\n\n"+
"📊 Проект ID: %s\n"+
"📝 Название: %s\n"+
"🏷 Статус: %s",
project.ID,
project.Title,
project.Status,
successText := fmt.Sprintf(msgSuccessChooseWorkspace, project.ID, project.Title, project.Status)
kb := Keyboard(
Row(Button("Мои проекты", "my_projects")),
Row(Button("Главное меню", "main_menu")),
)
b.Edit(successText, Keyboard(
Row(Button("📋 Мои проекты", "my_projects")),
Row(Button("🏠 Главное меню", "main_menu")),
))
b.Edit(successText, kb)
case data == "back_to_select":
s.Enter(b, bot.EditMessage)