diff --git a/dashboard/src/assets/mdi-subset/materialdesignicons-subset.css b/dashboard/src/assets/mdi-subset/materialdesignicons-subset.css index bb882203a..548c0e20e 100644 --- a/dashboard/src/assets/mdi-subset/materialdesignicons-subset.css +++ b/dashboard/src/assets/mdi-subset/materialdesignicons-subset.css @@ -1,4 +1,4 @@ -/* Auto-generated MDI subset – 252 icons */ +/* Auto-generated MDI subset – 256 icons */ /* Do not edit manually. Run: pnpm run subset-icons */ @font-face { @@ -128,10 +128,22 @@ content: "\F00ED"; } +.mdi-calendar-blank-outline::before { + content: "\F0B66"; +} + +.mdi-calendar-clock-outline::before { + content: "\F16E1"; +} + .mdi-calendar-edit::before { content: "\F08A7"; } +.mdi-calendar-multiple::before { + content: "\F00F1"; +} + .mdi-calendar-plus::before { content: "\F00F3"; } @@ -832,6 +844,10 @@ content: "\F048A"; } +.mdi-send-clock-outline::before { + content: "\F1164"; +} + .mdi-server::before { content: "\F048B"; } diff --git a/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff b/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff index 6131c0411..a5eb156c7 100644 Binary files a/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff and b/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff differ diff --git a/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff2 b/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff2 index 2ac3e9228..f434af15b 100644 Binary files a/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff2 and b/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff2 differ diff --git a/dashboard/src/i18n/locales/en-US/features/conversation.json b/dashboard/src/i18n/locales/en-US/features/conversation.json index 3e8cb7128..d6f28706b 100644 --- a/dashboard/src/i18n/locales/en-US/features/conversation.json +++ b/dashboard/src/i18n/locales/en-US/features/conversation.json @@ -31,6 +31,10 @@ "createdAt": "Created At", "updatedAt": "Updated At", "actions": "Actions" + }, + "umoDisplay": { + "parsed": "Parsed", + "raw": "UMO" } }, "actions": { @@ -97,6 +101,8 @@ "batchDeletePartial": "Delete completed: {deleted} successful, {failed} failed", "exportSuccess": "Export successful", "exportError": "Export failed", - "noItemSelectedForExport": "Please select conversations to export first" + "noItemSelectedForExport": "Please select conversations to export first", + "copySuccess": "Copied", + "copyError": "Copy failed" } -} \ No newline at end of file +} diff --git a/dashboard/src/i18n/locales/en-US/features/cron.json b/dashboard/src/i18n/locales/en-US/features/cron.json index fdb20243a..6635a6fbe 100644 --- a/dashboard/src/i18n/locales/en-US/features/cron.json +++ b/dashboard/src/i18n/locales/en-US/features/cron.json @@ -1,10 +1,14 @@ { + "header": { + "eyebrow": "Automation", + "live": "Live Sync" + }, "page": { "title": "Future Task Management", "beta": "Experimental", "subtitle": "See scheduled tasks for AstrBot. AstrBot will wake up, run them, and deliver the results.", "proactive": { - "supported": "Proactive delivery is available on: {platforms}", + "supported": "Proactive delivery is available only on the configured platforms below", "unsupported": "No proactive messaging platforms enabled. Turn them on in Platform settings." } }, @@ -15,8 +19,41 @@ "cancel": "Cancel", "submit": "Create" }, + "overview": { + "totalTasks": "Total Tasks", + "totalTasksNote": "Registered future tasks", + "enabledTasks": "Enabled Tasks", + "enabledTasksNote": "Tasks ready to wake and run", + "oneOffTasks": "One-off Tasks", + "recurringTasksNote": "{count} recurring tasks", + "proactivePlatforms": "Proactive Platforms", + "proactivePlatformsNote": "Platforms able to deliver results proactively" + }, + "section": { + "registered": { + "title": "Task List", + "subtitle": "Review the registered tasks, execution timing, and current state" + }, + "delivery": { + "title": "Delivery Status", + "subtitle": "After a task runs, results are proactively sent back through supported platforms", + "support": "Proactive delivery", + "available": "Available", + "unavailable": "Unavailable", + "enabledPlatforms": "Enabled platforms" + }, + "quickCreate": { + "title": "Quick Create", + "runMode": "Task mode", + "target": "Targeting" + }, + "platforms": { + "title": "Supported Platforms" + } + }, "table": { "title": "Registered Tasks", + "subtitle": "Track cron setup, session target, last run history, and enabled state", "empty": "No tasks yet.", "headers": { "name": "Name", diff --git a/dashboard/src/i18n/locales/en-US/features/subagent.json b/dashboard/src/i18n/locales/en-US/features/subagent.json index 7bfb0b08d..e9ea127f5 100644 --- a/dashboard/src/i18n/locales/en-US/features/subagent.json +++ b/dashboard/src/i18n/locales/en-US/features/subagent.json @@ -1,4 +1,7 @@ { + "header": { + "eyebrow": "Orchestration" + }, "page": { "title": "SubAgent Orchestration", "beta": "Experimental", @@ -8,9 +11,20 @@ "refresh": "Refresh", "save": "Save", "add": "Add SubAgent", + "expand": "Expand", + "collapse": "Collapse", "delete": "Delete", "close": "Close" }, + "overview": { + "totalAgents": "Total SubAgents", + "totalAgentsNote": "Configured delegate agents", + "enabledAgents": "Enabled Agents", + "enabledAgentsNote": "Agents available for handoff", + "mainOrchestration": "Main Orchestration", + "boundPersonas": "Bound Personas", + "boundPersonasNote": "Agents with an attached persona" + }, "switches": { "enable": "Enable SubAgent orchestration", "enableHint": "Enable sub-agent functionality", @@ -23,7 +37,9 @@ }, "section": { "title": "SubAgents", - "globalSettings": "Global Settings" + "subtitle": "Configure delegate agents, personas, and descriptions for the main LLM", + "globalSettings": "Global Settings", + "agentSetup": "Agent Setup" }, "cards": { "statusEnabled": "Enabled", @@ -33,7 +49,9 @@ "switchLabel": "Enable", "previewTitle": "Preview: handoff tool shown to the main LLM", "personaChip": "Persona: {id}", - "personaPreview": "PERSONA PREVIEW" + "personaPreview": "Persona Preview", + "noDescription": "No description yet", + "previewHint": "Review the currently selected persona to verify the handoff target." }, "form": { "nameLabel": "Agent name (used for transfer_to_{name})", @@ -48,6 +66,9 @@ "messages": { "loadConfigFailed": "Failed to load config", "loadPersonaFailed": "Failed to load persona list", + "unsavedChangesNotice": "You have unsaved changes on this page. Save before leaving.", + "unsavedChangesLeaveConfirm": "You have unsaved changes. Leaving will discard them. Continue?", + "unsavedChangesReloadConfirm": "You have unsaved changes. Reloading will discard them. Continue?", "nameMissing": "A SubAgent is missing a name", "nameInvalid": "Invalid SubAgent name: only lowercase letters/numbers/underscores, starting with a letter", "nameDuplicate": "Duplicate SubAgent name: {name}", diff --git a/dashboard/src/i18n/locales/ru-RU/features/conversation.json b/dashboard/src/i18n/locales/ru-RU/features/conversation.json index 33ebefa74..ea29fe1b1 100644 --- a/dashboard/src/i18n/locales/ru-RU/features/conversation.json +++ b/dashboard/src/i18n/locales/ru-RU/features/conversation.json @@ -31,6 +31,10 @@ "createdAt": "Создан", "updatedAt": "Обновлен", "actions": "Действия" + }, + "umoDisplay": { + "parsed": "Разобрано", + "raw": "UMO" } }, "actions": { @@ -97,6 +101,8 @@ "batchDeletePartial": "Удаление завершено: успешно {deleted}, ошибок {failed}", "exportSuccess": "Экспорт завершен", "exportError": "Ошибка экспорта", - "noItemSelectedForExport": "Сначала выберите диалоги для экспорта" + "noItemSelectedForExport": "Сначала выберите диалоги для экспорта", + "copySuccess": "Скопировано", + "copyError": "Не удалось скопировать" } -} \ No newline at end of file +} diff --git a/dashboard/src/i18n/locales/ru-RU/features/cron.json b/dashboard/src/i18n/locales/ru-RU/features/cron.json index 5bc98ab13..a7d36864f 100644 --- a/dashboard/src/i18n/locales/ru-RU/features/cron.json +++ b/dashboard/src/i18n/locales/ru-RU/features/cron.json @@ -1,10 +1,14 @@ { + "header": { + "eyebrow": "Automation", + "live": "Живая синхронизация" + }, "page": { "title": "Запланированные задачи", "beta": "Экспериментальные функции", "subtitle": "Управление будущими задачами AstrBot. Бот автоматически проснется, выполнит задачу и отправит результат. Требуется включить «Проактивные способности» в конфигурации.", "proactive": { - "supported": "Отправка результатов поддерживается на платформах: {platforms}", + "supported": "Отправка результатов поддерживается только на указанных ниже настроенных платформах", "unsupported": "Нет платформ, поддерживающих проактивные сообщения. Включите их в настройках платформ." } }, @@ -15,8 +19,41 @@ "cancel": "Отмена", "submit": "Создать" }, + "overview": { + "totalTasks": "Всего задач", + "totalTasksNote": "Все зарегистрированные будущие задачи", + "enabledTasks": "Активные задачи", + "enabledTasksNote": "Задачи, которые будут автоматически выполнены", + "oneOffTasks": "Разовые задачи", + "recurringTasksNote": "Повторяющихся задач: {count}", + "proactivePlatforms": "Проактивные платформы", + "proactivePlatformsNote": "Платформы, способные отправлять результат сами" + }, + "section": { + "registered": { + "title": "Список задач", + "subtitle": "Просматривайте зарегистрированные задачи, время запуска и состояние" + }, + "delivery": { + "title": "Статус доставки", + "subtitle": "После выполнения задачи результат будет отправлен обратно через поддерживаемые платформы", + "support": "Проактивная доставка", + "available": "Доступна", + "unavailable": "Недоступна", + "enabledPlatforms": "Включенные платформы" + }, + "quickCreate": { + "title": "Быстрое создание", + "runMode": "Режим задачи", + "target": "Целевой контекст" + }, + "platforms": { + "title": "Поддерживаемые платформы" + } + }, "table": { "title": "Список задач", + "subtitle": "Отслеживайте cron, целевую сессию, историю запусков и состояние", "empty": "Задач пока нет.", "headers": { "name": "Имя", @@ -63,4 +100,4 @@ "createSuccess": "Задача создана", "createFailed": "Ошибка создания" } -} \ No newline at end of file +} diff --git a/dashboard/src/i18n/locales/ru-RU/features/subagent.json b/dashboard/src/i18n/locales/ru-RU/features/subagent.json index 368bd2046..4f6b298b4 100644 --- a/dashboard/src/i18n/locales/ru-RU/features/subagent.json +++ b/dashboard/src/i18n/locales/ru-RU/features/subagent.json @@ -1,4 +1,7 @@ { + "header": { + "eyebrow": "Orchestration" + }, "page": { "title": "Оркестрация SubAgent", "beta": "Экспериментально", @@ -8,9 +11,20 @@ "refresh": "Обновить", "save": "Сохранить", "add": "Добавить SubAgent", + "expand": "Развернуть", + "collapse": "Свернуть", "delete": "Удалить", "close": "Закрыть" }, + "overview": { + "totalAgents": "Всего SubAgent", + "totalAgentsNote": "Количество настроенных под-агентов", + "enabledAgents": "Активные агенты", + "enabledAgentsNote": "Под-агенты, доступные для handoff", + "mainOrchestration": "Основная оркестрация", + "boundPersonas": "Привязанные персонажи", + "boundPersonasNote": "Под-агенты с выбранной персоной" + }, "switches": { "enable": "Включить оркестрацию SubAgent", "enableHint": "Включить функциональность под-агентов", @@ -23,7 +37,9 @@ }, "section": { "title": "Субагенты", - "globalSettings": "Глобальные настройки" + "subtitle": "Настройте делегируемых агентов, персонажей и описания для основного LLM", + "globalSettings": "Глобальные настройки", + "agentSetup": "Настройка агента" }, "cards": { "statusEnabled": "Включено", @@ -33,7 +49,9 @@ "switchLabel": "Включить", "previewTitle": "Предпросмотр: инструмент handoff, видимый основному LLM", "personaChip": "Персонаж: {id}", - "personaPreview": "ПРЕДПРОСМОТР ПЕРСОНАЖА" + "personaPreview": "Предпросмотр персонажа", + "noDescription": "Описание пока не задано", + "previewHint": "Просмотрите выбранную персону, чтобы проверить цель handoff." }, "form": { "nameLabel": "Имя агента (используется для transfer_to_{name})", @@ -48,6 +66,9 @@ "messages": { "loadConfigFailed": "Не удалось загрузить конфигурацию", "loadPersonaFailed": "Не удалось загрузить список персонажей", + "unsavedChangesNotice": "На странице есть несохраненные изменения. Сохраните их перед уходом.", + "unsavedChangesLeaveConfirm": "Есть несохраненные изменения. При уходе со страницы они будут потеряны. Продолжить?", + "unsavedChangesReloadConfirm": "Есть несохраненные изменения. Обновление конфигурации их сбросит. Продолжить?", "nameMissing": "У SubAgent отсутствует имя", "nameInvalid": "Недопустимое имя SubAgent: только строчные латинские буквы/цифры/подчеркивания, должно начинаться с буквы", "nameDuplicate": "Дублирующееся имя SubAgent: {name}", @@ -62,4 +83,4 @@ "subtitle": "Добавьте первого под-агента, чтобы начать", "action": "Создать первого агента" } -} \ No newline at end of file +} diff --git a/dashboard/src/i18n/locales/zh-CN/core/navigation.json b/dashboard/src/i18n/locales/zh-CN/core/navigation.json index 02370bcce..82fd48704 100644 --- a/dashboard/src/i18n/locales/zh-CN/core/navigation.json +++ b/dashboard/src/i18n/locales/zh-CN/core/navigation.json @@ -5,7 +5,7 @@ "providers": "模型提供商", "commands": "指令管理", "persona": "人格设定", - "subagent": "SubAgent 编排", + "subagent": "子代理编排", "toolUse": "MCP", "extension": "插件", "extensionTabs": { diff --git a/dashboard/src/i18n/locales/zh-CN/features/conversation.json b/dashboard/src/i18n/locales/zh-CN/features/conversation.json index 8a5ca6eb5..583c6f44d 100644 --- a/dashboard/src/i18n/locales/zh-CN/features/conversation.json +++ b/dashboard/src/i18n/locales/zh-CN/features/conversation.json @@ -22,7 +22,7 @@ }, "table": { "headers": { - "title": "对话标题", + "title": "标题", "platform": "机器人 ID", "type": "消息类型", "cid": "对话 ID", @@ -31,6 +31,10 @@ "createdAt": "创建时间", "updatedAt": "更新时间", "actions": "操作" + }, + "umoDisplay": { + "parsed": "解析后", + "raw": "UMO" } }, "actions": { @@ -97,6 +101,8 @@ "batchDeletePartial": "删除完成:成功 {deleted} 个,失败 {failed} 个", "exportSuccess": "导出成功", "exportError": "导出失败", - "noItemSelectedForExport": "请先选择要导出的对话" + "noItemSelectedForExport": "请先选择要导出的对话", + "copySuccess": "复制成功", + "copyError": "复制失败" } -} \ No newline at end of file +} diff --git a/dashboard/src/i18n/locales/zh-CN/features/cron.json b/dashboard/src/i18n/locales/zh-CN/features/cron.json index 05df8aa63..5e8b4b572 100644 --- a/dashboard/src/i18n/locales/zh-CN/features/cron.json +++ b/dashboard/src/i18n/locales/zh-CN/features/cron.json @@ -1,22 +1,59 @@ { + "header": { + "eyebrow": "Automation", + "live": "实时同步" + }, "page": { "title": "未来任务管理", "beta": "实验性", - "subtitle": "查看给 AstrBot 布置的未来任务。AstrBot 将会被自动唤醒、执行任务,然后将结果告知任务布置方。需要先在配置文件中启用“主动型能力”。", + "subtitle": "AstrBot 可以被自动唤醒然后执行任务,并将结果告知任务布置方。需要先在配置文件中启用“主动型能力”。", "proactive": { - "supported": "主动发送结果仅支持以下您已配置的平台:{platforms}", + "supported": "主动发送结果仅支持以下您已配置的平台", "unsupported": "暂无支持主动消息的平台,请在平台设置中开启。" } }, "actions": { - "create": "新建任务", + "create": "新建", "refresh": "刷新", "delete": "删除", "cancel": "取消", "submit": "创建" }, + "overview": { + "totalTasks": "任务总数", + "totalTasksNote": "当前已注册的未来任务", + "enabledTasks": "启用任务", + "enabledTasksNote": "执行器会按计划唤醒并运行", + "oneOffTasks": "一次性任务", + "recurringTasksNote": "循环任务 {count} 个", + "proactivePlatforms": "主动平台", + "proactivePlatformsNote": "已开启主动消息的平台数量" + }, + "section": { + "registered": { + "title": "任务列表", + "subtitle": "集中查看当前注册任务、执行时间与启用状态" + }, + "delivery": { + "title": "投递状态", + "subtitle": "未来任务执行后的结果,会通过支持主动消息的平台回传", + "support": "主动投递", + "available": "可用", + "unavailable": "不可用", + "enabledPlatforms": "已启用平台" + }, + "quickCreate": { + "title": "快速创建", + "runMode": "任务模式", + "target": "目标定位" + }, + "platforms": { + "title": "适用平台" + } + }, "table": { "title": "已注册任务", + "subtitle": "支持查看 cron、会话、最近执行记录与启用状态", "empty": "暂无任务。", "headers": { "name": "名称", diff --git a/dashboard/src/i18n/locales/zh-CN/features/subagent.json b/dashboard/src/i18n/locales/zh-CN/features/subagent.json index 9c7a43d7f..cd49ae432 100644 --- a/dashboard/src/i18n/locales/zh-CN/features/subagent.json +++ b/dashboard/src/i18n/locales/zh-CN/features/subagent.json @@ -1,39 +1,57 @@ { + "header": { + "eyebrow": "Subagent Orchestration" + }, "page": { - "title": "SubAgent 编排", + "title": "子代理编排", "beta": "实验性", - "subtitle": "主 LLM 可直接使用自身工具,也可通过 handoff 分派给各个 SubAgent。" + "subtitle": "主代理可直接使用自身工具,也可将部分任务委派给各个子代理,完成更复杂的任务,避免主代理上下文过长。" }, "actions": { "refresh": "刷新", "save": "保存", - "add": "新增 SubAgent", + "add": "新增子代理", + "expand": "展开设置", + "collapse": "收起设置", "delete": "删除", "close": "关闭" }, + "overview": { + "totalAgents": "子代理总数", + "totalAgentsNote": "当前已配置的子代理数量", + "enabledAgents": "启用中的 Agent", + "enabledAgentsNote": "会参与 handoff 编排的子代理", + "mainOrchestration": "主编排状态", + "boundPersonas": "已绑定 Persona", + "boundPersonasNote": "完成角色绑定的子代理数量" + }, "switches": { - "enable": "启用 SubAgent 编排", + "enable": "启用子代理编排", "enableHint": "启用子代理功能", - "dedupe": "主 LLM 去重重复工具(与 SubAgent 重叠的工具将被隐藏)", - "dedupeHint": "从主代理中移除重复工具" + "dedupe": "主 LLM 去重重复工具(与子代理重叠的工具将被隐藏)", + "dedupeHint": "从主代理中移除与子代理重复的工具" }, "description": { - "disabled": "不启动:SubAgent 关闭;主 LLM 按 persona 规则挂载工具(默认全部),并直接调用。", - "enabled": "启动:主 LLM 会保留自身工具并挂载 transfer_to_* 委派工具。若开启“去重重复工具”,与 SubAgent 指定的工具重叠部分会从主 LLM 工具集中移除。" + "disabled": "未启动子代理编排功能。", + "enabled": "子代理将作为工具放在主代理的工具集中,主代理会在适当的时机调用子代理完成任务。" }, "section": { - "title": "SubAgents 配置", - "globalSettings": "全局设置" + "title": "子代理配置", + "subtitle": "为主代理配置可委派的子代理、人格与描述信息", + "globalSettings": "全局设置", + "agentSetup": "Agent 设置" }, "cards": { "statusEnabled": "启用", "statusDisabled": "停用", - "unnamed": "未命名 SubAgent", + "unnamed": "未命名子代理", "transferPrefix": "transfer_to_{name}", "switchLabel": "启用", "previewTitle": "预览:主 LLM 将看到的 handoff 工具", "personaChip": "Persona: {id}", - "noDescription": "暂无描述" + "noDescription": "暂无描述", + "personaPreview": "人格预览", + "previewHint": "这里展示当前所选 Persona 的预览,便于确认 handoff 目标。" }, "form": { "nameLabel": "Agent 名称(用于 transfer_to_{name})", @@ -41,7 +59,7 @@ "providerLabel": "Chat Provider(可选)", "providerHint": "留空表示跟随全局默认 provider。", "personaLabel": "选择人格设定", - "personaHint": "SubAgent 将直接继承所选 Persona 的系统设定与工具。在人格设定页管理和新建人格。", + "personaHint": "子代理 将直接继承所选 Persona 的系统设定与工具。在人格设定页管理和新建人格。", "personaPreview": "人格预览", "descriptionLabel": "对主 LLM 的描述(用于决定是否 handoff)", "descriptionHint": "这段会作为 transfer_to_* 工具的描述给主 LLM 看,建议简短明确。" @@ -49,17 +67,20 @@ "messages": { "loadConfigFailed": "获取配置失败", "loadPersonaFailed": "获取 Persona 列表失败", - "nameMissing": "存在未填写名称的 SubAgent", - "nameInvalid": "SubAgent 名称不合法:仅允许英文小写字母/数字/下划线,且需以字母开头", - "nameDuplicate": "SubAgent 名称重复:{name}", - "personaMissing": "SubAgent {name} 未选择 Persona", + "unsavedChangesNotice": "当前页面有未保存修改,请在离开前保存。", + "unsavedChangesLeaveConfirm": "当前页面有未保存修改,离开后将丢失这些更改。是否继续离开?", + "unsavedChangesReloadConfirm": "当前页面有未保存修改,刷新配置会丢失这些更改。是否继续刷新?", + "nameMissing": "存在未填写名称的子代理", + "nameInvalid": "子代理名称不合法:仅允许英文小写字母/数字/下划线,且需以字母开头", + "nameDuplicate": "子代理名称重复:{name}", + "personaMissing": "子代理 {name} 未选择 Persona", "saveSuccess": "保存成功", "saveFailed": "保存失败", "nameRequired": "名称必填", "namePattern": "仅支持小写字母、数字和下划线" }, "empty": { - "title": "未配置 SubAgent", + "title": "未配置子代理", "subtitle": "添加一个新的子代理以开始", "action": "创建第一个 Agent" } diff --git a/dashboard/src/styles/dashboard-shell.css b/dashboard/src/styles/dashboard-shell.css new file mode 100644 index 000000000..83a4bd31e --- /dev/null +++ b/dashboard/src/styles/dashboard-shell.css @@ -0,0 +1,292 @@ +.dashboard-page { + --dashboard-bg: rgb(var(--v-theme-background)); + --dashboard-surface: rgb(var(--v-theme-surface)); + --dashboard-text: rgb(var(--v-theme-on-surface)); + --dashboard-muted: rgba(var(--v-theme-on-surface), 0.68); + --dashboard-subtle: rgba(var(--v-theme-on-surface), 0.56); + --dashboard-border: rgba(var(--v-theme-on-surface), 0.1); + --dashboard-border-strong: rgba(var(--v-theme-on-surface), 0.14); + --dashboard-soft: rgba(var(--v-theme-primary), 0.08); + --dashboard-soft-strong: rgba(var(--v-theme-primary), 0.14); + min-height: 100%; + background: var(--dashboard-bg); +} + +.dashboard-page.is-dark { + --dashboard-border: rgba(var(--v-theme-on-surface), 0.14); + --dashboard-border-strong: rgba(var(--v-theme-on-surface), 0.18); + --dashboard-soft: rgba(var(--v-theme-primary), 0.12); + --dashboard-soft-strong: rgba(var(--v-theme-primary), 0.18); +} + +.dashboard-shell { + max-width: 1560px; + margin: 0 auto; + color: var(--dashboard-text); + font-family: "SF Pro Display", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; +} + +.dashboard-header { + display: flex; + justify-content: space-between; + align-items: flex-end; + gap: 24px; + margin-bottom: 24px; +} + +.dashboard-header-main { + min-width: 0; +} + +.dashboard-eyebrow { + margin-bottom: 8px; + color: var(--dashboard-subtle); + font-size: 12px; + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.dashboard-title { + margin: 0; + font-size: clamp(32px, 4vw, 44px); + line-height: 1.04; + font-weight: 700; + letter-spacing: -0.04em; +} + +.dashboard-subtitle { + margin: 10px 0 0; + color: var(--dashboard-muted); + font-size: 15px; + line-height: 1.6; + max-width: 860px; +} + +.dashboard-header-meta, +.dashboard-header-actions { + display: flex; + align-items: center; + gap: 10px; + flex-wrap: wrap; +} + +.dashboard-pill { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 10px 14px; + border: 1px solid var(--dashboard-border); + border-radius: 999px; + background: var(--dashboard-surface); + color: var(--dashboard-muted); + font-size: 13px; +} + +.dashboard-overview-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 16px; + margin-bottom: 20px; +} + +.dashboard-card { + border: 1px solid var(--dashboard-border); + border-radius: 16px; + background: var(--dashboard-surface); +} + +.dashboard-card--padded { + padding: 22px; +} + +.dashboard-overview-card { + padding: 20px 20px 18px; +} + +.dashboard-card-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + border-radius: 12px; + background: var(--dashboard-soft); + color: rgb(var(--v-theme-primary)); +} + +.dashboard-card-label { + margin-top: 12px; + color: var(--dashboard-muted); + font-size: 13px; + font-weight: 500; +} + +.dashboard-card-value { + margin-top: 8px; + font-size: clamp(24px, 2vw, 34px); + line-height: 1.1; + font-weight: 700; + letter-spacing: -0.03em; + overflow-wrap: anywhere; +} + +.dashboard-card-note { + margin-top: 8px; + color: var(--dashboard-subtle); + font-size: 12px; + line-height: 1.5; + overflow-wrap: anywhere; +} + +.dashboard-section-head { + display: flex; + justify-content: space-between; + align-items: flex-end; + gap: 16px; + margin-bottom: 16px; +} + +.dashboard-section-title { + font-size: 19px; + font-weight: 650; + letter-spacing: -0.02em; + line-height: 1.3; + overflow-wrap: anywhere; +} + +.dashboard-section-subtitle { + margin-top: 6px; + color: var(--dashboard-muted); + font-size: 13px; + line-height: 1.6; +} + +.dashboard-section-actions { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 10px; + flex-wrap: wrap; +} + +.dashboard-split-grid { + display: grid; + grid-template-columns: 1.6fr 0.9fr; + gap: 20px; + align-items: stretch; +} + +.dashboard-split-grid > * { + min-width: 0; + width: 100%; +} + +.dashboard-side-column { + display: grid; + gap: 20px; + align-content: start; + min-width: 0; +} + +.dashboard-meta-list { + display: grid; + gap: 10px; + margin-top: 18px; + padding-top: 14px; + border-top: 1px solid var(--dashboard-border); +} + +.dashboard-meta-row, +.dashboard-list-row { + display: flex; + justify-content: space-between; + align-items: center; + gap: 12px; + min-width: 0; +} + +.dashboard-meta-row { + color: var(--dashboard-muted); + font-size: 14px; +} + +.dashboard-list { + display: grid; + gap: 12px; +} + +.dashboard-list-row { + padding: 12px 0; + border-bottom: 1px solid var(--dashboard-border); + font-size: 14px; +} + +.dashboard-list-row:last-child { + border-bottom: 0; +} + +.dashboard-list-label { + color: var(--dashboard-text); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.dashboard-empty { + color: var(--dashboard-muted); + font-size: 14px; +} + +.dashboard-scrollable { + max-height: 360px; + overflow-y: auto; + padding-right: 6px; +} + +.dashboard-form-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 16px; +} + +.dashboard-form-grid--single { + grid-template-columns: 1fr; +} + +.dashboard-dialog-card { + border: 1px solid var(--dashboard-border); + border-radius: 18px; +} + +@media (max-width: 1280px) { + .dashboard-overview-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +@media (max-width: 1080px) { + .dashboard-split-grid, + .dashboard-form-grid { + grid-template-columns: 1fr; + } +} + +@media (max-width: 900px) { + .dashboard-header, + .dashboard-section-head { + flex-direction: column; + align-items: flex-start; + } +} + +@media (max-width: 640px) { + .dashboard-overview-grid { + grid-template-columns: 1fr; + } + + .dashboard-card--padded, + .dashboard-overview-card { + padding: 18px; + } +} diff --git a/dashboard/src/views/ConversationPage.vue b/dashboard/src/views/ConversationPage.vue index 111a82202..c2430b25a 100644 --- a/dashboard/src/views/ConversationPage.vue +++ b/dashboard/src/views/ConversationPage.vue @@ -71,30 +71,60 @@ class="elevation-0" :items-per-page="pagination.page_size" :items-per-page-options="pageSizeOptions" show-select return-object :disabled="loading" @update:options="handleTableOptions"> -