From b76871caf09993ff92a9856efb276bafa5efd912 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sun, 13 Sep 2026 08:20:14 +0300 Subject: [PATCH] =?UTF-8?q?:bug:=20fix(chat):=20=D0=B2=D0=B5=D1=80=D0=BD?= =?UTF-8?q?=D1=83=D1=82=D1=8C=20=D1=81=D0=B2=D1=91=D1=80=D0=BD=D1=83=D1=82?= =?UTF-8?q?=D1=8B=D0=B9=20=D1=81=D0=BF=D0=B8=D1=81=D0=BE=D0=BA=20=D0=B4?= =?UTF-8?q?=D0=B8=D0=B0=D0=BB=D0=BE=D0=B3=D0=BE=D0=B2,=20=D0=B7=D0=B5?= =?UTF-8?q?=D0=BB=D1=91=D0=BD=D1=8B=D0=B9=20=D0=B0=D0=BA=D1=86=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=20=D0=BF=D0=BE=20=D1=83=D0=BC=D0=BE=D0=BB=D1=87=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Кнопка «Показать список» жила только в шапке переписки. При пустом списке или просто без выбранного диалога переписки нет — свёрнутый список оказывался не вернуть ничем. Теперь кнопка есть и в пустой области, на том же месте, что и в шапке. Сценарий закрыт e2e-тестом. Цвет продукта по умолчанию — зелёный #0f9b8e: он же первый в палитре акцентов профиля. Прежний синий остался вторым пресетом. Co-Authored-By: Claude Opus 5 --- apps/backend/chatballs/i18n/messages/en.py | 2 +- apps/backend/chatballs/i18n/messages/ru.py | 2 +- apps/backend/chatballs/identity/models.py | 2 +- .../conversations/ConversationWorkspace.tsx | 12 +++++++++++- .../features/profile/ProfileAppearanceCard.tsx | 2 +- apps/internal-ui/src/i18n/en.ts | 2 +- apps/internal-ui/src/i18n/ru.ts | 2 +- apps/internal-ui/src/shared/appearance.ts | 6 +++--- apps/internal-ui/src/styles/base.css | 2 +- tests/e2e/internal-ui.spec.ts | 15 +++++++++++++++ 10 files changed, 36 insertions(+), 11 deletions(-) diff --git a/apps/backend/chatballs/i18n/messages/en.py b/apps/backend/chatballs/i18n/messages/en.py index a93645a..d797ce0 100644 --- a/apps/backend/chatballs/i18n/messages/en.py +++ b/apps/backend/chatballs/i18n/messages/en.py @@ -113,7 +113,7 @@ MESSAGES: dict[str, object] = { "portals.invalid_section": "Invalid section", "portals.not_found": "Portal not found", "portals.section_not_found": "Section not found", - "profile.accent_hex": "The accent is a HEX colour like #1677ff", + "profile.accent_hex": "The accent is a HEX colour like #0f9b8e", "profile.choose_photo_file": "Choose a photo file", "profile.link_not_found": "Link not found", "profile.notification_bot_not_found": "Notification bot not found", diff --git a/apps/backend/chatballs/i18n/messages/ru.py b/apps/backend/chatballs/i18n/messages/ru.py index 84a1375..1b6e9e8 100644 --- a/apps/backend/chatballs/i18n/messages/ru.py +++ b/apps/backend/chatballs/i18n/messages/ru.py @@ -117,7 +117,7 @@ MESSAGES: dict[str, object] = { "portals.invalid_section": "Некорректный раздел", "portals.not_found": "Портал не найден", "portals.section_not_found": "Раздел не найден", - "profile.accent_hex": "Акцент — HEX-цвет вида #1677ff", + "profile.accent_hex": "Акцент — HEX-цвет вида #0f9b8e", "profile.choose_photo_file": "Выберите файл фото", "profile.link_not_found": "Привязка не найдена", "profile.notification_bot_not_found": "Бот уведомлений не найден", diff --git a/apps/backend/chatballs/identity/models.py b/apps/backend/chatballs/identity/models.py index 5f15e1b..619729d 100644 --- a/apps/backend/chatballs/identity/models.py +++ b/apps/backend/chatballs/identity/models.py @@ -75,7 +75,7 @@ class HumanUser(AbstractUser): # без этой отметки принимался бы второй раз ещё полторы минуты. totp_last_counter = models.BigIntegerField(default=0) # Внешний вид — глобальная настройка пользователя (не membership): - # тема и акцентный HEX-цвет; пустой акцент — дефолтный синий #1677ff. + # тема и акцентный HEX-цвет; пустой акцент — цвет продукта #0f9b8e. ui_theme = models.CharField(max_length=8, choices=UiTheme.choices, default=UiTheme.SYSTEM) ui_accent = models.CharField(max_length=9, blank=True) # Язык интерфейса — тоже глобальная настройка пользователя, а не diff --git a/apps/internal-ui/src/features/conversations/ConversationWorkspace.tsx b/apps/internal-ui/src/features/conversations/ConversationWorkspace.tsx index 7ae27d4..7d25e19 100644 --- a/apps/internal-ui/src/features/conversations/ConversationWorkspace.tsx +++ b/apps/internal-ui/src/features/conversations/ConversationWorkspace.tsx @@ -4,6 +4,7 @@ import { CallOverlay } from "./CallOverlay"; import { Composer } from "./Composer"; import { ConversationThread } from "./ConversationThread"; import { DialogList } from "./DialogList"; +import { IconButton } from "../../shared/ui-controls"; import { claimConversation, closeConversation, @@ -227,7 +228,16 @@ export function ConversationWorkspace({ isOwner = false, viewerId = null, listTi hint={hint} /> {!selectedDialog && ( -
{t("conversations.pick_conversation")}
+
+ {/* Свёрнутый список без выбранного диалога: вернуть его больше неоткуда — + шапки переписки, где живёт та же кнопка, здесь нет. */} + {listCollapsed && ( +
+ setListCollapsed(false)} /> +
+ )} +
{t("conversations.pick_conversation")}
+
)} {selectedDialog && (
diff --git a/apps/internal-ui/src/features/profile/ProfileAppearanceCard.tsx b/apps/internal-ui/src/features/profile/ProfileAppearanceCard.tsx index 5c6a312..8d7cefa 100644 --- a/apps/internal-ui/src/features/profile/ProfileAppearanceCard.tsx +++ b/apps/internal-ui/src/features/profile/ProfileAppearanceCard.tsx @@ -94,7 +94,7 @@ export function ProfileAppearanceCard({ user, onUserUpdated }: { user: SessionUs setCustomAccent(event.target.value)} onKeyDown={(event) => { diff --git a/apps/internal-ui/src/i18n/en.ts b/apps/internal-ui/src/i18n/en.ts index 065c0ba..80e3966 100644 --- a/apps/internal-ui/src/i18n/en.ts +++ b/apps/internal-ui/src/i18n/en.ts @@ -1228,7 +1228,7 @@ export const en: Record = { "profile.create_agent": "Create an agent", "profile.current": "current", "profile.current_password": "Current password", - "profile.custom_colour_hex_value_like": "A custom colour is a HEX value like #1677ff", + "profile.custom_colour_hex_value_like": "A custom colour is a HEX value like #0f9b8e", "profile.dark": "Dark", "profile.disconnect": "Disconnect", "profile.drag_resize_double_click_reset": "Drag to resize, double-click to reset", diff --git a/apps/internal-ui/src/i18n/ru.ts b/apps/internal-ui/src/i18n/ru.ts index 7b8470e..f5fdce2 100644 --- a/apps/internal-ui/src/i18n/ru.ts +++ b/apps/internal-ui/src/i18n/ru.ts @@ -1229,7 +1229,7 @@ export const ru = { "profile.create_agent": "Создать агента", "profile.current": "текущая", "profile.current_password": "Текущий пароль", - "profile.custom_colour_hex_value_like": "Свой цвет — HEX вида #1677ff", + "profile.custom_colour_hex_value_like": "Свой цвет — HEX вида #0f9b8e", "profile.dark": "Тёмная", "profile.disconnect": "Отключить", "profile.drag_resize_double_click_reset": "Потяните, двойной клик — сбросить", diff --git a/apps/internal-ui/src/shared/appearance.ts b/apps/internal-ui/src/shared/appearance.ts index 0d76748..6c8dbe0 100644 --- a/apps/internal-ui/src/shared/appearance.ts +++ b/apps/internal-ui/src/shared/appearance.ts @@ -7,13 +7,13 @@ import { t } from "../i18n"; export type UiTheme = "LIGHT" | "DARK" | "SYSTEM"; -export const DEFAULT_ACCENT = "#1677ff"; +export const DEFAULT_ACCENT = "#0f9b8e"; -// Пресеты акцента из дизайн-базлайна v2 (Tweaks макета). +// Пресеты акцента; первый — цвет продукта по умолчанию. export const ACCENT_PRESETS: Array<[string, string]> = [ + ["#0f9b8e", t("shared.teal")], ["#1677ff", t("shared.blue")], ["#6d5dfc", t("shared.indigo")], - ["#0f9b8e", t("shared.teal")], ["#e8590c", t("shared.orange")], ]; diff --git a/apps/internal-ui/src/styles/base.css b/apps/internal-ui/src/styles/base.css index 65b1368..8ef0e65 100644 --- a/apps/internal-ui/src/styles/base.css +++ b/apps/internal-ui/src/styles/base.css @@ -29,7 +29,7 @@ --primary — акцент на экране: в тёмной теме он приглушён подложкой карточки, как в дизайн-базлайне v2 (accentMuted). Производные оттенки считаются от сырого акцента, а не от приглушённого. */ - --accent: #1677ff; + --accent: #0f9b8e; --primary: var(--accent); --primary-hover: color-mix(in srgb, var(--accent) 88%, black); --primary-bg: color-mix(in srgb, var(--accent) 10%, var(--surface-card)); diff --git a/tests/e2e/internal-ui.spec.ts b/tests/e2e/internal-ui.spec.ts index 10258a3..0292f43 100644 --- a/tests/e2e/internal-ui.spec.ts +++ b/tests/e2e/internal-ui.spec.ts @@ -802,3 +802,18 @@ test("подсветка тура встаёт ровно по элементу await page.screenshot({ path: "test-results/onboarding-tour-settings.png" }); }); + +test("свёрнутый список диалогов возвращается и без выбранного диалога", async ({ page }) => { + await login(page, OWNER_IDENTITY); + await expect(page).toHaveURL(/\/chat$/); + + // Кнопка возврата жила только в шапке переписки, а при пустом списке + // переписки нет — список оказывался не вернуть. + await page.getByRole("button", { name: "Скрыть список" }).click(); + await expect(page.locator(".sales-dialogs.is-list-collapsed")).toBeVisible(); + await expect(page.locator(".sales-dialog-list")).toBeHidden(); + + await page.getByRole("button", { name: "Показать список" }).click(); + await expect(page.locator(".sales-dialogs.is-list-collapsed")).toHaveCount(0); + await expect(page.locator(".sales-dialog-list")).toBeVisible(); +});