@nextclaw/ui 0.26.2 → 0.26.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/dist/.vite/manifest.json +366 -365
- package/dist/assets/{account-panel-ZM2qzKF4.js → account-panel-DVi_jhkG.js} +1 -1
- package/dist/assets/{api-Cjq-o1VN.js → api-BZvNpFOS.js} +2 -2
- package/dist/assets/app-presenter-provider-BcYL-VNe.js +124 -0
- package/dist/assets/{appearance-settings-page-B4zouKzg.js → appearance-settings-page-AZNBzLmT.js} +1 -1
- package/dist/assets/{book-open-AteA89HX.js → book-open-CmRdT3N1.js} +1 -1
- package/dist/assets/card-CdRBL1E0.js +1 -0
- package/dist/assets/{channels-list-page-fj8kMo-T.js → channels-list-page-eZN74FN3.js} +2 -2
- package/dist/assets/{circle-dashed-LSYZTzM7.js → circle-dashed-HOgt3gIJ.js} +1 -1
- package/dist/assets/{client-DudCRJw4.js → client-DKKbdJ6Q.js} +1 -1
- package/dist/assets/config-split-page-BA3V6b3Q.js +1 -0
- package/dist/assets/{confirm-dialog-DShT64F6.js → confirm-dialog-8vqYZ0wy.js} +1 -1
- package/dist/assets/context-menu-DHVVdHzN.js +1 -0
- package/dist/assets/{createLucideIcon-D7hvIHV-.js → createLucideIcon-DE0sB9Nu.js} +1 -1
- package/dist/assets/{desktop-capabilities-page-CzqzFZUY.js → desktop-capabilities-page-B9-B9k1A.js} +1 -1
- package/dist/assets/{desktop-update-config-CgeQ0Ffo.js → desktop-update-config-Cfr3IRUe.js} +1 -1
- package/dist/assets/{dialog-C7glmAQJ.js → dialog-BUfWO8hr.js} +2 -2
- package/dist/assets/{doc-browser-context-BlhBAOLH.js → doc-browser-context-ClLgMbxd.js} +1 -1
- package/dist/assets/doc-browser-w8q1j0jL.js +1 -0
- package/dist/assets/{download-BYgECE0n.js → download-CKqS1Ksj.js} +1 -1
- package/dist/assets/{es2015-CsjAAQ6X.js → es2015-BiB05Sav.js} +1 -1
- package/dist/assets/{extensions-qYL-NpL3.js → extensions-vPD4dGqt.js} +1 -1
- package/dist/assets/{eye-BBuTzJ53.js → eye-bKzylu3p.js} +1 -1
- package/dist/assets/{form-actions-CLGWO52v.js → form-actions-CCoxz33Q.js} +1 -1
- package/dist/assets/{i18n-qBGEbcW6.js → i18n-OGmF0Ws_.js} +2 -2
- package/dist/assets/{keyboard-shortcuts-settings-page-B-wK_6zG.js → keyboard-shortcuts-settings-page-D8rosOVh.js} +1 -1
- package/dist/assets/loader-circle-Clq1Gtb1.js +1 -0
- package/dist/assets/{login-page-Cd84lpVV.js → login-page-BT3GV3Sb.js} +1 -1
- package/dist/assets/login-page-DKId3By8.js +1 -0
- package/dist/assets/main-bEWCGDHr.js +2 -0
- package/dist/assets/main-i18n-catalog.config-Bpu5GcwF.js +1 -0
- package/dist/assets/main-kqMRTwOs.css +1 -0
- package/dist/assets/mcp-marketplace-page-CZIP6j3L.js +1 -0
- package/dist/assets/{model-config-page-D0DQlSDa.js → model-config-page-D21a-BO0.js} +1 -1
- package/dist/assets/{navigation-link-32iM1-e6.js → navigation-link-DC-Pku0Y.js} +1 -1
- package/dist/assets/panel-app-BYfQu_TS.js +1 -0
- package/dist/assets/panel-app-i18n-catalog.config-D44qmtfk.js +1 -0
- package/dist/assets/panelStandalone-BRg7B1EI.css +1 -0
- package/dist/assets/{panelStandalone-C9EKaApN.js → panelStandalone-CX8X2hjh.js} +2 -2
- package/dist/assets/{privacy-settings-page-Bxxx12OO.js → privacy-settings-page-e0LFHZJm.js} +1 -1
- package/dist/assets/projects-Rki7Fmth.js +1 -0
- package/dist/assets/provider-models-DFQgF4hS.js +1 -0
- package/dist/assets/provider-scoped-model-input-DaONL0j_.js +1 -0
- package/dist/assets/providers-config-page-CEOhQlMe.js +1 -0
- package/dist/assets/{puzzle-CWHfFyYN.js → puzzle-D_TiFXOv.js} +1 -1
- package/dist/assets/{pwa-CiGUjpcd.js → pwa-C9ac_1dg.js} +1 -1
- package/dist/assets/{refresh-cw-y3L6PyLt.js → refresh-cw-BG8VfcdA.js} +1 -1
- package/dist/assets/remote-DkSx5x4R.js +1 -0
- package/dist/assets/{rotate-cw-CNE9qSHi.js → rotate-cw-DPEegUU2.js} +1 -1
- package/dist/assets/{runtime-config-page-5o98T-TD.js → runtime-config-page-DDT1dVLt.js} +1 -1
- package/dist/assets/{save-B0p5a0ET.js → save-CPlctBjT.js} +1 -1
- package/dist/assets/{search-config-page-CpGcnIzi.js → search-config-page-CDwmd6eX.js} +1 -1
- package/dist/assets/{secrets-config-page-C4VTiW3r.js → secrets-config-page-1OvgmwPv.js} +1 -1
- package/dist/assets/security-config-Pv4CM-kw.js +1 -0
- package/dist/assets/{select-CctTN205.js → select-Y9IEbx9x.js} +1 -1
- package/dist/assets/service-apps-panel-DPrLeF3N.js +1 -0
- package/dist/assets/{settings-2-EPflrNk6.js → settings-2-CrGx9_De.js} +1 -1
- package/dist/assets/{status-dot-CensgJZC.js → status-dot-Cb8ewlUr.js} +1 -1
- package/dist/assets/{tag-chip-Bjzb4-qW.js → tag-chip-D-6aPuuh.js} +1 -1
- package/dist/assets/{theme-provider-hlle7Skk.js → theme-provider-BjF1Eowc.js} +1 -1
- package/dist/assets/{trash-2-C5KH5Rw9.js → trash-2-DER2EJKK.js} +1 -1
- package/dist/assets/{use-config-CPl_F79t.js → use-config-BM5jC65L.js} +1 -1
- package/dist/assets/{use-desktop-capabilities-CEg9-DrQ.js → use-desktop-capabilities-ezKJwKqg.js} +1 -1
- package/dist/assets/{use-viewport-layout-CPZUmTPi.js → use-viewport-layout-vmbQUNT6.js} +1 -1
- package/dist/assets/x-DSz9cGhy.js +1 -0
- package/dist/index.html +34 -34
- package/dist/panel-standalone.html +11 -11
- package/package.json +3 -3
- package/src/app/components/layout/__tests__/sidebar.layout.test.tsx +2 -2
- package/src/app/components/layout/page-layout.tsx +5 -2
- package/src/app/components/layout/sidebar-rail.styles.ts +3 -3
- package/src/app/configs/__tests__/app-navigation.config.test.ts +10 -0
- package/src/app/configs/app-navigation.config.ts +6 -2
- package/src/app/styles/charcoal-theme.css +0 -3
- package/src/app/styles/design-system.css +18 -6
- package/src/app/styles/island-theme.css +2 -15
- package/src/features/agents/components/agent-details-dialog.tsx +1 -1
- package/src/features/agents/components/agents-page.tsx +5 -3
- package/src/features/app-data/components/app-data-removal-choice.tsx +1 -1
- package/src/features/apps/components/app-package-card.tsx +7 -6
- package/src/features/channels/pages/channels-list-page.tsx +1 -1
- package/src/features/chat/components/chat-sidebar-list-mode-switch.tsx +1 -1
- package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +28 -16
- package/src/features/chat/components/conversation/chat-conversation-content.tsx +8 -2
- package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +3 -3
- package/src/features/chat/components/conversation/chat-conversation-header.tsx +4 -4
- package/src/features/chat/components/layout/__tests__/chat-sidebar-session-area.test.tsx +6 -4
- package/src/features/chat/components/layout/__tests__/chat-sidebar-toolbar.test.tsx +22 -1
- package/src/features/chat/components/layout/chat-page-shell.tsx +1 -1
- package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +10 -14
- package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +50 -12
- package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +4 -4
- package/src/features/chat/components/layout/chat-sidebar.tsx +2 -2
- package/src/features/chat/features/conversation/components/session-queued-input-rows.tsx +1 -1
- package/src/features/chat/features/message/components/chat-message-list.container.tsx +12 -1
- package/src/features/chat/features/message/components/chat-tool-call-stress-harness.tsx +32 -2
- package/src/features/chat/features/message/hooks/__tests__/use-chat-message-virtualizer.test.tsx +7 -5
- package/src/features/chat/features/message/hooks/use-chat-message-virtualizer.ts +7 -3
- package/src/features/chat/features/session/components/__tests__/chat-sidebar-project-groups.test.tsx +1 -1
- package/src/features/chat/features/session/components/chat-mobile-session-row.tsx +2 -2
- package/src/features/chat/features/session/components/chat-sidebar-context-card.tsx +1 -1
- package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +1 -1
- package/src/features/chat/features/session/components/chat-sidebar-session-item.tsx +7 -5
- package/src/features/chat/features/session/components/chat-sidebar-session-list.tsx +45 -10
- package/src/features/chat/features/session/components/session-header/__tests__/chat-session-header-actions.test.tsx +1 -1
- package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +3 -5
- package/src/features/chat/features/session/components/session-header/chat-session-header-menu-item.tsx +4 -3
- package/src/features/chat/features/session/components/session-header/chat-session-more-actions-menu.tsx +3 -0
- package/src/features/chat/features/session/components/session-header/chat-session-switcher-groups.tsx +6 -6
- package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx +6 -5
- package/src/features/chat/features/session-type/components/chat-session-type-option-item.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +0 -1
- package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-prompt-suggestions.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +1 -1
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumb-browser.tsx +2 -2
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +2 -2
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +1 -1
- package/src/features/chat/features/workspace/components/child-sessions/chat-session-child-sessions.tsx +2 -2
- package/src/features/chat/features/workspace/components/file-content-preview/workspace-spreadsheet-preview.tsx +2 -2
- package/src/features/chat/features/workspace/components/overview/chat-session-continuous-attention.tsx +3 -3
- package/src/features/chat/features/workspace/components/overview/chat-session-token-usage.tsx +1 -1
- package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +4 -3
- package/src/features/chat/features/workspace/components/project-files/workspace-new-folder-tree-item.tsx +2 -1
- package/src/features/chat/features/workspace/components/project-files/workspace-project-files-toolbar.tsx +3 -1
- package/src/features/chat/features/workspace/components/session-cron-job-content.tsx +3 -3
- package/src/features/chat/features/workspace/components/workspace-file-content-preview.tsx +2 -2
- package/src/features/chat/features/workspace/components/workspace-markdown-outline.tsx +1 -1
- package/src/features/cron/components/cron-config.tsx +3 -2
- package/src/features/cron/components/cron-job-detail-dialog.tsx +1 -1
- package/src/features/cron/components/cron-job-row.tsx +7 -7
- package/src/features/cron/components/cron-task-discovery.tsx +1 -1
- package/src/features/inbox/components/inbox-delivery-content.tsx +1 -1
- package/src/features/inbox/pages/inbox-page.tsx +25 -29
- package/src/features/marketplace/components/curated-shelves/marketplace-curated-shelves.tsx +2 -2
- package/src/features/marketplace/components/curated-shelves/marketplace-shelf-card.tsx +2 -2
- package/src/features/marketplace/components/marketplace-list-card.tsx +4 -4
- package/src/features/marketplace/components/marketplace-page-parts.tsx +4 -3
- package/src/features/marketplace/components/marketplace-page.tsx +4 -4
- package/src/features/marketplace/components/mcp/mcp-marketplace-card.tsx +2 -2
- package/src/features/marketplace/components/mcp/mcp-marketplace-page.tsx +3 -3
- package/src/features/panel-apps/components/panel-app-list-item.tsx +3 -3
- package/src/features/panel-apps/components/panel-app-open-standalone-menu-item.tsx +3 -1
- package/src/features/projects/components/project-overview.tsx +1 -1
- package/src/features/projects/pages/project-home-page.tsx +11 -2
- package/src/features/projects/pages/projects-page.test.tsx +4 -2
- package/src/features/pwa/components/pwa-install-entry.tsx +1 -1
- package/src/features/right-panel-resources/components/__tests__/page-resource-sidebar-nav.test.tsx +9 -1
- package/src/features/right-panel-resources/components/page-resource-sidebar-nav.tsx +1 -1
- package/src/features/right-panel-resources/components/right-panel-resource-home-page.tsx +1 -1
- package/src/features/service-apps/components/service-action-row.tsx +3 -3
- package/src/features/service-apps/components/service-app-list-item.tsx +4 -4
- package/src/features/service-apps/components/service-apps-panel.tsx +1 -1
- package/src/features/settings/components/config/provider-model-list.tsx +5 -5
- package/src/features/settings/components/config/provider-model-suggestions-panel.tsx +4 -4
- package/src/features/settings/components/config/provider-pill-selector.tsx +1 -1
- package/src/features/settings/pages/appearance-settings-page.tsx +2 -2
- package/src/features/settings/pages/providers-config-page.tsx +6 -6
- package/src/features/side-dock/components/side-dock.tsx +4 -4
- package/src/index.css +4 -0
- package/src/platforms/desktop/components/desktop-window-chrome.tsx +1 -1
- package/src/platforms/mobile/components/mobile-app-shell.tsx +1 -1
- package/src/platforms/mobile/components/mobile-bottom-nav.tsx +10 -9
- package/src/platforms/mobile/components/mobile-settings-shell.tsx +24 -23
- package/src/platforms/mobile/components/mobile-topbar.tsx +10 -11
- package/src/shared/components/common/brand-header.tsx +1 -1
- package/src/shared/components/common/searchable-model-input.tsx +2 -2
- package/src/shared/components/config-split-page.tsx +3 -3
- package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +34 -2
- package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +38 -7
- package/src/shared/components/doc-browser/doc-browser.tsx +5 -1
- package/src/shared/components/path-picker/server-path-picker-locations.tsx +1 -1
- package/src/shared/components/settings/settings-page.tsx +1 -1
- package/src/shared/components/ui/actions/__tests__/icon-action-button.test.tsx +5 -5
- package/src/shared/components/ui/actions/action-feedback.ts +8 -0
- package/src/shared/components/ui/actions/icon-action-button.tsx +13 -12
- package/src/shared/components/ui/button.tsx +3 -3
- package/src/shared/components/ui/card.tsx +1 -1
- package/src/shared/components/ui/context-menu/context-menu-items.tsx +6 -5
- package/src/shared/components/ui/dialog.tsx +4 -3
- package/src/shared/components/ui/input.tsx +7 -2
- package/src/shared/components/ui/overlays/sheet.tsx +1 -1
- package/src/shared/components/ui/popover.tsx +1 -1
- package/src/shared/components/ui/select.tsx +3 -2
- package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +8 -6
- package/src/shared/components/ui/tabs.tsx +3 -3
- package/src/shared/components/ui/textarea.tsx +1 -0
- package/src/shared/components/workbench/workbench-surface-toolbar.tsx +3 -4
- package/src/shared/components/workbench/workbench-surface.tsx +2 -2
- package/src/shared/lib/i18n/locales/en-US/agents.json +2 -0
- package/src/shared/lib/i18n/locales/en-US/core.json +1 -0
- package/src/shared/lib/i18n/locales/en-US/desktop-update.json +1 -1
- package/src/shared/lib/i18n/locales/zh-CN/agents.json +2 -0
- package/src/shared/lib/i18n/locales/zh-CN/core.json +1 -0
- package/src/shared/lib/i18n/locales/zh-CN/desktop-update.json +1 -1
- package/dist/assets/app-presenter-provider-C02YPoMr.js +0 -124
- package/dist/assets/card-BLXvBstA.js +0 -1
- package/dist/assets/config-split-page-G7Kt2BnV.js +0 -1
- package/dist/assets/context-menu-rd7b_kVD.js +0 -1
- package/dist/assets/doc-browser-dBiR9Qi0.js +0 -1
- package/dist/assets/loader-circle-BA7EMkih.js +0 -1
- package/dist/assets/login-page-VdMyNkFf.js +0 -1
- package/dist/assets/main-CR0SrTBf.js +0 -2
- package/dist/assets/main-DXH6EdXI.css +0 -1
- package/dist/assets/main-i18n-catalog.config-Btp_OowF.js +0 -1
- package/dist/assets/mcp-marketplace-page-jacRwiI-.js +0 -1
- package/dist/assets/panel-app-CC0bVSu4.js +0 -1
- package/dist/assets/panel-app-i18n-catalog.config-LUSBp5Ce.js +0 -1
- package/dist/assets/panelStandalone-Y91OJkgV.css +0 -1
- package/dist/assets/projects-D56yAPNT.js +0 -1
- package/dist/assets/provider-models-C3frdXeW.js +0 -1
- package/dist/assets/provider-scoped-model-input-CYetrPYZ.js +0 -1
- package/dist/assets/providers-config-page-DESB1h8g.js +0 -1
- package/dist/assets/remote-DiGFV8nP.js +0 -1
- package/dist/assets/security-config-C5-RQVpS.js +0 -1
- package/dist/assets/service-apps-panel-CKE5HKNY.js +0 -1
- package/dist/assets/x--xxUvHKW.js +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import {
|
|
1
|
+
import { useState, type ReactNode } from "react";
|
|
2
|
+
import { ChatCollapsibleContent } from "@nextclaw/agent-chat-ui";
|
|
3
|
+
import { ChevronRight, MessageSquareText } from "lucide-react";
|
|
3
4
|
import type { NcpSessionListItemView } from "@/features/chat/features/ncp/hooks/use-ncp-session-list-view";
|
|
4
5
|
import type {
|
|
5
6
|
ChatSidebarDateGroup,
|
|
@@ -8,6 +9,7 @@ import type {
|
|
|
8
9
|
import { ChatSidebarProjectGroups } from "@/features/chat/features/session/components/chat-sidebar-project-groups";
|
|
9
10
|
import type { ChatSessionTypeOption } from "@/features/chat/features/session-type/utils/chat-session-type.utils";
|
|
10
11
|
import { t } from "@/shared/lib/i18n";
|
|
12
|
+
import { cn } from "@/shared/lib/utils";
|
|
11
13
|
|
|
12
14
|
type SessionTypeOption = ChatSessionTypeOption;
|
|
13
15
|
|
|
@@ -32,6 +34,41 @@ function ChatSidebarEmptyState({ label }: { label: string }) {
|
|
|
32
34
|
);
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
function ChatSidebarSessionGroup({ group, variant, renderSessionItem }: {
|
|
38
|
+
group: ChatSidebarDateGroup;
|
|
39
|
+
variant: 'desktop' | 'mobile';
|
|
40
|
+
renderSessionItem: ChatSidebarSessionListProps['renderSessionItem'];
|
|
41
|
+
}) {
|
|
42
|
+
const [open, setOpen] = useState(true);
|
|
43
|
+
return (
|
|
44
|
+
<div>
|
|
45
|
+
<button
|
|
46
|
+
type="button"
|
|
47
|
+
aria-expanded={open}
|
|
48
|
+
onClick={() => setOpen((value) => !value)}
|
|
49
|
+
className={cn(
|
|
50
|
+
'group/session-heading flex w-full cursor-pointer items-center justify-between gap-2 rounded-xl text-left text-xs font-medium text-muted-foreground outline-none transition-colors duration-base hover:bg-[var(--interaction-hover)] hover:text-foreground',
|
|
51
|
+
variant === 'mobile' ? 'min-h-9 px-4' : 'min-h-7 px-2',
|
|
52
|
+
)}
|
|
53
|
+
>
|
|
54
|
+
<span className="truncate">{group.label}</span>
|
|
55
|
+
<ChevronRight
|
|
56
|
+
aria-hidden="true"
|
|
57
|
+
className={cn(
|
|
58
|
+
'h-3 w-3 shrink-0 opacity-0 transition-[opacity,transform] duration-200 group-hover/session-heading:opacity-100 motion-reduce:transition-none',
|
|
59
|
+
open && 'rotate-90',
|
|
60
|
+
)}
|
|
61
|
+
/>
|
|
62
|
+
</button>
|
|
63
|
+
<ChatCollapsibleContent open={open}>{() => (
|
|
64
|
+
<div className={variant === 'mobile' ? undefined : 'space-y-0.5'}>
|
|
65
|
+
{group.items.map(renderSessionItem)}
|
|
66
|
+
</div>
|
|
67
|
+
)}</ChatCollapsibleContent>
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
35
72
|
export function ChatSidebarSessionList({
|
|
36
73
|
variant = 'desktop',
|
|
37
74
|
defaultSessionType,
|
|
@@ -72,14 +109,12 @@ export function ChatSidebarSessionList({
|
|
|
72
109
|
return (
|
|
73
110
|
<div className={variant === 'mobile' ? undefined : 'space-y-2'}>
|
|
74
111
|
{groups.map((group) => (
|
|
75
|
-
<
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
112
|
+
<ChatSidebarSessionGroup
|
|
113
|
+
key={group.label}
|
|
114
|
+
group={group}
|
|
115
|
+
variant={variant}
|
|
116
|
+
renderSessionItem={renderSessionItem}
|
|
117
|
+
/>
|
|
83
118
|
))}
|
|
84
119
|
</div>
|
|
85
120
|
);
|
|
@@ -187,7 +187,7 @@ describe('ChatSessionHeaderActions', () => {
|
|
|
187
187
|
|
|
188
188
|
const actionGroup = screen.getByRole('button', { name: 'More actions' }).parentElement;
|
|
189
189
|
|
|
190
|
-
expect(actionGroup?.className).toContain('gap-
|
|
190
|
+
expect(actionGroup?.className).toContain('max-md:gap-0');
|
|
191
191
|
expect(screen.getByRole('button', { name: 'Open session workspace' }).className).toContain('h-7');
|
|
192
192
|
expect(screen.getByRole('button', { name: 'Open session workspace' }).className).toContain('w-7');
|
|
193
193
|
});
|
package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
import { Braces, FolderOpen, PanelRightClose, PanelRightOpen, Trash2 } from 'lucide-react';
|
|
3
|
-
import { IconActionButton } from '@/shared/components/ui/actions/icon-action-button';
|
|
3
|
+
import { IconActionButton, IconActionGroup } from '@/shared/components/ui/actions/icon-action-button';
|
|
4
4
|
import { useChatSessionProject } from '@/features/chat/features/session/hooks/use-chat-session-project';
|
|
5
5
|
import { ChatSessionHeaderMenuItem } from './chat-session-header-menu-item';
|
|
6
6
|
import { ChatSessionMoreActionsMenu } from './chat-session-more-actions-menu';
|
|
@@ -8,8 +8,6 @@ import { ChatSessionMetadataDialog } from './chat-session-metadata-dialog';
|
|
|
8
8
|
import { ChatSessionProjectDialog } from './chat-session-project-dialog';
|
|
9
9
|
import { t } from '@/shared/lib/i18n';
|
|
10
10
|
|
|
11
|
-
const SESSION_HEADER_ACTION_GROUP_CLASS = 'flex shrink-0 items-center gap-1.5';
|
|
12
|
-
|
|
13
11
|
type ChatSessionHeaderActionsProps = {
|
|
14
12
|
sessionKey: string | null;
|
|
15
13
|
sessionTitle?: string;
|
|
@@ -60,7 +58,7 @@ export function ChatSessionHeaderActions({
|
|
|
60
58
|
};
|
|
61
59
|
|
|
62
60
|
return (
|
|
63
|
-
<
|
|
61
|
+
<IconActionGroup>
|
|
64
62
|
<IconActionButton
|
|
65
63
|
icon={
|
|
66
64
|
isWorkspaceOpen ? (
|
|
@@ -123,6 +121,6 @@ export function ChatSessionHeaderActions({
|
|
|
123
121
|
/>
|
|
124
122
|
</>
|
|
125
123
|
) : null}
|
|
126
|
-
</
|
|
124
|
+
</IconActionGroup>
|
|
127
125
|
);
|
|
128
126
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { LucideIcon } from 'lucide-react';
|
|
2
2
|
import { cn } from '@/shared/lib/utils';
|
|
3
|
+
import { ACTION_FEEDBACK, ACTION_MENU_ITEM_CLASS } from '@/shared/components/ui/actions/action-feedback';
|
|
3
4
|
|
|
4
5
|
type ChatSessionHeaderMenuItemProps = {
|
|
5
6
|
icon: LucideIcon;
|
|
@@ -20,10 +21,10 @@ export function ChatSessionHeaderMenuItem({
|
|
|
20
21
|
<button
|
|
21
22
|
type="button"
|
|
22
23
|
className={cn(
|
|
23
|
-
|
|
24
|
+
ACTION_MENU_ITEM_CLASS,
|
|
24
25
|
destructive
|
|
25
|
-
?
|
|
26
|
-
:
|
|
26
|
+
? ACTION_FEEDBACK.destructive
|
|
27
|
+
: `text-foreground ${ACTION_FEEDBACK.item}`
|
|
27
28
|
)}
|
|
28
29
|
onClick={onClick}
|
|
29
30
|
disabled={disabled}
|
|
@@ -22,6 +22,7 @@ type ChatSessionMoreActionsMenuProps = {
|
|
|
22
22
|
disabled?: boolean;
|
|
23
23
|
triggerSize?: IconActionButtonSize;
|
|
24
24
|
triggerTone?: IconActionButtonTone;
|
|
25
|
+
triggerTooltipSide?: 'top' | 'bottom';
|
|
25
26
|
className?: string;
|
|
26
27
|
};
|
|
27
28
|
|
|
@@ -39,6 +40,7 @@ export function ChatSessionMoreActionsMenu({
|
|
|
39
40
|
disabled = false,
|
|
40
41
|
triggerSize = 'md',
|
|
41
42
|
triggerTone = 'default',
|
|
43
|
+
triggerTooltipSide = 'bottom',
|
|
42
44
|
className,
|
|
43
45
|
}: ChatSessionMoreActionsMenuProps) {
|
|
44
46
|
const [isOpen, setIsOpen] = useState(false);
|
|
@@ -59,6 +61,7 @@ export function ChatSessionMoreActionsMenu({
|
|
|
59
61
|
label={t('chatSessionMoreActions')}
|
|
60
62
|
size={triggerSize}
|
|
61
63
|
tone={triggerTone}
|
|
64
|
+
tooltipSide={triggerTooltipSide}
|
|
62
65
|
className={className}
|
|
63
66
|
disabled={disabled}
|
|
64
67
|
onClick={(event) => event.stopPropagation()}
|
|
@@ -66,9 +66,9 @@ function ChatSessionSwitchItem({
|
|
|
66
66
|
type="button"
|
|
67
67
|
aria-current={active ? "page" : undefined}
|
|
68
68
|
className={cn(
|
|
69
|
-
"flex w-full min-w-0 items-start gap-2 rounded-lg px-2.5 py-
|
|
69
|
+
"flex w-full min-w-0 items-start gap-2 rounded-lg px-2.5 py-1.5 text-left transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border",
|
|
70
70
|
active
|
|
71
|
-
? "bg-accent text-accent-foreground"
|
|
71
|
+
? "bg-accent/60 text-accent-foreground"
|
|
72
72
|
: "text-foreground hover:bg-[var(--interaction-hover)] hover:text-accent-foreground",
|
|
73
73
|
)}
|
|
74
74
|
onClick={() => onSelect(session.key)}
|
|
@@ -101,7 +101,7 @@ function ChatSessionSwitchItem({
|
|
|
101
101
|
</span>
|
|
102
102
|
) : null}
|
|
103
103
|
</span>
|
|
104
|
-
<span className="mt-0.5 flex min-w-0 items-center gap-2 text-[11px] text-muted-foreground">
|
|
104
|
+
<span className="mt-0.5 flex min-w-0 items-center gap-2 text-[11px] text-muted-foreground/75">
|
|
105
105
|
<span className="min-w-0 truncate">{previewText}</span>
|
|
106
106
|
<span className="shrink-0">{trailingText}</span>
|
|
107
107
|
</span>
|
|
@@ -177,12 +177,12 @@ function ChatSessionSwitchProjectGroup({
|
|
|
177
177
|
aria-controls={contentId}
|
|
178
178
|
aria-expanded={!isCollapsed}
|
|
179
179
|
aria-label={actionLabel}
|
|
180
|
-
className="group flex h-
|
|
180
|
+
className="group flex h-8 w-full min-w-0 items-center gap-1.5 rounded-lg px-2 text-left text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
|
|
181
181
|
onClick={() => onToggleCollapsed(group.projectRoot)}
|
|
182
182
|
>
|
|
183
183
|
<Folder className="h-3.5 w-3.5 shrink-0" aria-hidden="true" />
|
|
184
184
|
<span
|
|
185
|
-
className="min-w-0 flex-1 truncate text-[
|
|
185
|
+
className="min-w-0 flex-1 truncate text-[13px] font-medium"
|
|
186
186
|
title={group.projectRoot}
|
|
187
187
|
>
|
|
188
188
|
{group.projectName}
|
|
@@ -222,7 +222,7 @@ export function ChatSessionSwitcherGroups({
|
|
|
222
222
|
projectGroups: ChatSidebarProjectGroup[];
|
|
223
223
|
}) {
|
|
224
224
|
return (
|
|
225
|
-
<div className="space-y-
|
|
225
|
+
<div className="space-y-0.5">
|
|
226
226
|
{isProjectFirstView
|
|
227
227
|
? projectGroups.map((group) => (
|
|
228
228
|
<ChatSessionSwitchProjectGroup
|
package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx
CHANGED
|
@@ -29,7 +29,7 @@ import { cn } from "@/shared/lib/utils";
|
|
|
29
29
|
import { useProjects } from "@/shared/hooks/use-projects";
|
|
30
30
|
|
|
31
31
|
const SWITCHER_TRIGGER_CLASS =
|
|
32
|
-
"group inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-md px-
|
|
32
|
+
"group inline-flex min-w-0 max-w-full items-center gap-1.5 max-md:gap-1 rounded-md px-2 py-1 text-sm font-medium text-foreground transition-colors hover:bg-[var(--interaction-hover)] hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border";
|
|
33
33
|
|
|
34
34
|
function ChatSessionTitle({ title }: { title: string }) {
|
|
35
35
|
return (
|
|
@@ -165,9 +165,9 @@ function ChatSessionTitleSwitcherPopover({
|
|
|
165
165
|
</PopoverTrigger>
|
|
166
166
|
<ChatPopoverContent
|
|
167
167
|
align="start"
|
|
168
|
-
className="w-[22rem] max-w-[calc(100vw-2rem)] p-0"
|
|
168
|
+
className="flex w-[22rem] max-w-[calc(100vw-2rem)] flex-col overflow-hidden p-0"
|
|
169
169
|
>
|
|
170
|
-
<div className="space-y-2 border-b border-border px-3 py-2">
|
|
170
|
+
<div className="shrink-0 space-y-2 border-b border-border/40 px-3 py-2">
|
|
171
171
|
<div className="flex items-center justify-between gap-3">
|
|
172
172
|
<div className="text-[11px] font-medium uppercase tracking-wider text-muted-foreground/75">
|
|
173
173
|
{t("chatSessionSwitcherTitle")}
|
|
@@ -180,16 +180,17 @@ function ChatSessionTitleSwitcherPopover({
|
|
|
180
180
|
<div className="relative">
|
|
181
181
|
<Search className="pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground/65" />
|
|
182
182
|
<Input
|
|
183
|
+
density="compact"
|
|
183
184
|
value={searchQuery}
|
|
184
185
|
onChange={(event) => setSearchQuery(event.target.value)}
|
|
185
186
|
placeholder={t("chatSearchSessionPlaceholder")}
|
|
186
187
|
aria-label={t("chatSearchSessionPlaceholder")}
|
|
187
|
-
className="h-8 rounded-lg bg-
|
|
188
|
+
className="h-8 rounded-lg border-0 bg-muted/50 pl-8 pr-2"
|
|
188
189
|
autoFocus
|
|
189
190
|
/>
|
|
190
191
|
</div>
|
|
191
192
|
</div>
|
|
192
|
-
<div className="max-h-80 overflow-y-auto p-1.5">
|
|
193
|
+
<div className="min-h-0 max-h-80 overflow-y-auto overscroll-contain p-1.5">
|
|
193
194
|
{isLoading ? (
|
|
194
195
|
<ChatSessionTitleSwitcherLoadingState />
|
|
195
196
|
) : hasVisibleGroups ? (
|
package/src/features/chat/features/session-type/components/chat-session-type-option-item.tsx
CHANGED
|
@@ -27,7 +27,7 @@ export function ChatSessionTypeOptionItem(props: {
|
|
|
27
27
|
onClick={onSelect}
|
|
28
28
|
className={cn(
|
|
29
29
|
"w-full rounded-2xl px-3 py-2.5 text-left transition-colors",
|
|
30
|
-
selected ? "bg-
|
|
30
|
+
selected ? "bg-[var(--interaction-selection)]" : "hover:bg-[var(--interaction-hover)]",
|
|
31
31
|
disabled ? "cursor-not-allowed opacity-70" : null,
|
|
32
32
|
)}
|
|
33
33
|
>
|
|
@@ -55,7 +55,7 @@ export function ChatWelcomeProjectPicker({
|
|
|
55
55
|
</PopoverTrigger>
|
|
56
56
|
<ChatPopoverContent
|
|
57
57
|
align="start"
|
|
58
|
-
className="flex w-[min(20rem,calc(100vw-1rem))] flex-col overflow-hidden
|
|
58
|
+
className="flex w-[min(20rem,calc(100vw-1rem))] flex-col overflow-hidden p-0"
|
|
59
59
|
style={{ maxHeight: PROJECT_PICKER_MAX_HEIGHT }}
|
|
60
60
|
>
|
|
61
61
|
<div className="shrink-0 px-3 pb-2 pt-3 text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground">
|
|
@@ -27,7 +27,7 @@ export function ChatWelcomePromptSuggestions({
|
|
|
27
27
|
key={suggestion.labelKey}
|
|
28
28
|
type="button"
|
|
29
29
|
onClick={() => onSelectPrompt(t(suggestion.promptKey))}
|
|
30
|
-
className="rounded-full bg-muted/55 px-3.5 py-2 text-xs font-medium text-muted-foreground transition-colors hover:bg-
|
|
30
|
+
className="rounded-full bg-muted/55 px-3.5 py-2 text-xs font-medium text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
|
31
31
|
>
|
|
32
32
|
{t(suggestion.labelKey)}
|
|
33
33
|
</button>
|
|
@@ -61,7 +61,7 @@ export function ChatWelcomeSessionTypePicker({
|
|
|
61
61
|
</PopoverTrigger>
|
|
62
62
|
<ChatPopoverContent
|
|
63
63
|
align="start"
|
|
64
|
-
className="flex w-[min(16rem,calc(100vw-1rem))] flex-col overflow-hidden
|
|
64
|
+
className="flex w-[min(16rem,calc(100vw-1rem))] flex-col overflow-hidden p-1.5"
|
|
65
65
|
style={{ maxHeight: SESSION_TYPE_PICKER_MAX_HEIGHT }}
|
|
66
66
|
>
|
|
67
67
|
<div className="min-h-0 flex-1 overflow-y-auto">
|
|
@@ -70,7 +70,7 @@ export function WorkspaceBreadcrumbBrowser({
|
|
|
70
70
|
<Fragment key={breadcrumb.path}>
|
|
71
71
|
<button
|
|
72
72
|
type="button"
|
|
73
|
-
className="h-5 rounded-sm px-1 text-left hover:bg-
|
|
73
|
+
className="h-5 rounded-sm px-1 text-left hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
|
|
74
74
|
onClick={() => onBrowsePathChange(breadcrumb.path)}
|
|
75
75
|
>
|
|
76
76
|
{breadcrumb.label}
|
|
@@ -100,7 +100,7 @@ export function WorkspaceBreadcrumbBrowser({
|
|
|
100
100
|
key={entry.path}
|
|
101
101
|
type="button"
|
|
102
102
|
className={cn(
|
|
103
|
-
"flex h-6 w-full items-center gap-1.5 rounded-sm px-1.5 text-left text-[11px] text-gray-700 transition-colors hover:bg-
|
|
103
|
+
"flex h-6 w-full items-center gap-1.5 rounded-sm px-1.5 text-left text-[11px] text-gray-700 transition-colors hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border",
|
|
104
104
|
entry.hidden ? "opacity-65" : null,
|
|
105
105
|
)}
|
|
106
106
|
onClick={() => openEntry(entry)}
|
package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx
CHANGED
|
@@ -43,9 +43,9 @@ function WorkspaceBreadcrumbSegmentButton({
|
|
|
43
43
|
type="button"
|
|
44
44
|
aria-current={segment.isCurrent ? 'page' : undefined}
|
|
45
45
|
className={cn(
|
|
46
|
-
'inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-sm px-1 text-[11px] leading-none transition-colors hover:bg-
|
|
46
|
+
'inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-sm px-1 text-[11px] leading-none transition-colors hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border',
|
|
47
47
|
segment.kind === 'workspace'
|
|
48
|
-
? 'bg-
|
|
48
|
+
? 'bg-[var(--interaction-selection)] text-foreground hover:bg-[var(--interaction-selection)]'
|
|
49
49
|
: segment.isCurrent
|
|
50
50
|
? 'bg-gray-200/70 text-gray-900'
|
|
51
51
|
: 'text-gray-500',
|
package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx
CHANGED
|
@@ -66,7 +66,7 @@ function WorkspaceOverviewEntry({
|
|
|
66
66
|
return (
|
|
67
67
|
<button
|
|
68
68
|
type="button"
|
|
69
|
-
className="group flex w-full items-center gap-3 rounded-lg border border-gray-200/80 bg-white px-3 py-3 text-left transition-colors hover:border-gray-300 hover:bg-
|
|
69
|
+
className="group flex w-full items-center gap-3 rounded-lg border border-gray-200/80 bg-white px-3 py-3 text-left transition-colors hover:border-gray-300 hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25"
|
|
70
70
|
onClick={onClick}
|
|
71
71
|
>
|
|
72
72
|
<span className="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-gray-100 text-gray-600">
|
|
@@ -27,7 +27,7 @@ export function ChatSessionChildSessions({
|
|
|
27
27
|
</div>
|
|
28
28
|
<button
|
|
29
29
|
type="button"
|
|
30
|
-
className="inline-flex shrink-0 items-center gap-1.5 rounded-md bg-primary px-2.5 py-1.5 text-xs font-semibold text-primary-foreground transition-colors hover:bg-primary
|
|
30
|
+
className="inline-flex shrink-0 items-center gap-1.5 rounded-md bg-primary px-2.5 py-1.5 text-xs font-semibold text-primary-foreground transition-colors hover:bg-[hsl(var(--primary-hover))] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25 disabled:cursor-not-allowed disabled:opacity-50"
|
|
31
31
|
disabled={!sessionKey}
|
|
32
32
|
onClick={() => presenter.chatThreadManager.openSideChatDraft(sessionKey)}
|
|
33
33
|
>
|
|
@@ -42,7 +42,7 @@ export function ChatSessionChildSessions({
|
|
|
42
42
|
{childSessionTabs.map((tab) => (
|
|
43
43
|
<div
|
|
44
44
|
key={tab.sessionKey}
|
|
45
|
-
className="group relative flex w-full items-center rounded-lg border border-gray-200/80 bg-white transition-colors hover:border-gray-300 hover:bg-
|
|
45
|
+
className="group relative flex w-full items-center rounded-lg border border-gray-200/80 bg-white transition-colors hover:border-gray-300 hover:bg-[var(--interaction-hover)]"
|
|
46
46
|
>
|
|
47
47
|
<button
|
|
48
48
|
type="button"
|
|
@@ -121,8 +121,8 @@ export function WorkspaceSpreadsheetPreview({
|
|
|
121
121
|
className={cn(
|
|
122
122
|
"h-7 shrink-0 rounded-md px-2.5 text-xs transition-colors",
|
|
123
123
|
sheet.name === activeSheet?.name
|
|
124
|
-
? "bg-
|
|
125
|
-
: "text-muted-foreground hover:bg-
|
|
124
|
+
? "bg-[var(--interaction-selection)] font-medium text-foreground"
|
|
125
|
+
: "text-muted-foreground hover:bg-[var(--interaction-hover)] hover:text-foreground",
|
|
126
126
|
)}
|
|
127
127
|
onClick={() => setSelectedSheetName(sheet.name)}
|
|
128
128
|
>
|
|
@@ -96,7 +96,7 @@ function ObservationRow({
|
|
|
96
96
|
type="button"
|
|
97
97
|
data-testid={`observation-${item.id}-${toggleAction}`}
|
|
98
98
|
disabled={isPending}
|
|
99
|
-
className="inline-flex items-center gap-1.5 rounded-md border border-gray-200 px-2.5 py-1.5 text-xs font-medium text-gray-700 transition-colors hover:bg-
|
|
99
|
+
className="inline-flex items-center gap-1.5 rounded-md border border-gray-200 px-2.5 py-1.5 text-xs font-medium text-gray-700 transition-colors hover:bg-[var(--interaction-hover)] disabled:cursor-not-allowed disabled:opacity-50"
|
|
100
100
|
onClick={() => onAction(toggleAction)}
|
|
101
101
|
>
|
|
102
102
|
{toggleAction === 'pause' ? <Pause className="h-3.5 w-3.5" /> : <Play className="h-3.5 w-3.5" />}
|
|
@@ -107,7 +107,7 @@ function ObservationRow({
|
|
|
107
107
|
type="button"
|
|
108
108
|
data-testid={`observation-${item.id}-remove`}
|
|
109
109
|
disabled={isPending}
|
|
110
|
-
className="inline-flex items-center gap-1.5 rounded-md border border-rose-200 px-2.5 py-1.5 text-xs font-medium text-rose-700 transition-colors hover:bg-
|
|
110
|
+
className="inline-flex items-center gap-1.5 rounded-md border border-rose-200 px-2.5 py-1.5 text-xs font-medium text-rose-700 transition-colors hover:bg-destructive/10 disabled:cursor-not-allowed disabled:opacity-50"
|
|
111
111
|
onClick={() => onAction('remove')}
|
|
112
112
|
>
|
|
113
113
|
<Trash2 className="h-3.5 w-3.5" />
|
|
@@ -179,7 +179,7 @@ export function ChatSessionContinuousAttention({ sessionKey }: { sessionKey: str
|
|
|
179
179
|
type="button"
|
|
180
180
|
role="tab"
|
|
181
181
|
aria-selected={activeGroup === group}
|
|
182
|
-
className={cn('flex-1 rounded-md px-3 py-2 text-xs font-medium transition-colors', activeGroup === group ? 'bg-
|
|
182
|
+
className={cn('flex-1 rounded-md px-3 py-2 text-xs font-medium transition-colors', activeGroup === group ? 'bg-[var(--interaction-selection)] text-foreground' : 'text-muted-foreground hover:bg-[var(--interaction-hover)] hover:text-foreground')}
|
|
183
183
|
onClick={() => setActiveGroup(group)}
|
|
184
184
|
>
|
|
185
185
|
{getGroupLabel(group)} <span className="ml-1 tabular-nums text-gray-400">{count}</span>
|
package/src/features/chat/features/workspace/components/overview/chat-session-token-usage.tsx
CHANGED
|
@@ -90,7 +90,7 @@ export function ChatSessionTokenUsage({ sessionKey }: { sessionKey: string | nul
|
|
|
90
90
|
<span>{t('chatWorkspaceTokenUsageLoadFailed')}</span>
|
|
91
91
|
<button
|
|
92
92
|
type="button"
|
|
93
|
-
className="shrink-0 rounded px-1.5 py-1 font-semibold text-gray-700 hover:bg-
|
|
93
|
+
className="shrink-0 rounded px-1.5 py-1 font-semibold text-gray-700 hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25"
|
|
94
94
|
onClick={() => void usageQuery.refetch()}
|
|
95
95
|
>
|
|
96
96
|
{t('chatWorkspaceTokenUsageRetry')}
|
package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx
CHANGED
|
@@ -355,8 +355,8 @@ export function WorkspaceDirectoryTreeEntry({
|
|
|
355
355
|
ref={rowRef}
|
|
356
356
|
data-workspace-tree-entry=""
|
|
357
357
|
className={cn(
|
|
358
|
-
'group flex h-[26px] w-full min-w-0 items-center text-gray-700 transition-colors hover:bg-
|
|
359
|
-
selected ? 'bg-
|
|
358
|
+
'group flex h-[26px] w-full min-w-0 items-center text-gray-700 transition-colors hover:bg-[var(--interaction-hover)] focus-within:bg-[var(--interaction-hover)]',
|
|
359
|
+
selected ? 'bg-[var(--interaction-selection)] hover:bg-[var(--interaction-selection)] focus-within:bg-[var(--interaction-selection)]' : null,
|
|
360
360
|
entry.hidden ? 'opacity-65' : null,
|
|
361
361
|
)}
|
|
362
362
|
style={{ paddingLeft: `${6 + level * 12}px` }}
|
|
@@ -371,9 +371,10 @@ export function WorkspaceDirectoryTreeEntry({
|
|
|
371
371
|
}}
|
|
372
372
|
>
|
|
373
373
|
<Input
|
|
374
|
+
density="compact"
|
|
374
375
|
autoFocus
|
|
375
376
|
aria-label={t('chatWorkspaceRenameName')}
|
|
376
|
-
className="h-6 min-w-0 flex-1 px-1.5
|
|
377
|
+
className="h-6 min-w-0 flex-1 px-1.5"
|
|
377
378
|
value={rename.name}
|
|
378
379
|
onChange={(event) => rename.updateName(event.target.value)}
|
|
379
380
|
onKeyDown={(event) => {
|
|
@@ -67,9 +67,10 @@ export function WorkspaceNewFolderTreeItem({
|
|
|
67
67
|
<Folder className="h-4 w-4 shrink-0 text-amber-500" />
|
|
68
68
|
)}
|
|
69
69
|
<Input
|
|
70
|
+
density="compact"
|
|
70
71
|
ref={inputRef}
|
|
71
72
|
aria-label={t(kind === 'file' ? 'chatWorkspaceFileName' : 'chatWorkspaceFolderName')}
|
|
72
|
-
className="h-7 min-w-0 flex-1 rounded-md px-2
|
|
73
|
+
className="h-7 min-w-0 flex-1 rounded-md px-2"
|
|
73
74
|
disabled={isCreating}
|
|
74
75
|
placeholder={t(kind === 'file' ? 'chatWorkspaceFileNamePlaceholder' : 'chatWorkspaceFolderNamePlaceholder')}
|
|
75
76
|
value={name}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChevronsUp, FilePlus2, FolderPlus, MoreVertical, RefreshCw } from 'lucide-react';
|
|
2
|
-
import { IconActionButton } from '@/shared/components/ui/actions/icon-action-button';
|
|
2
|
+
import { IconActionButton, IconActionGroup } from '@/shared/components/ui/actions/icon-action-button';
|
|
3
3
|
import { ContextMenuTrigger } from '@/shared/components/ui/context-menu/context-menu';
|
|
4
4
|
import { t } from '@/shared/lib/i18n';
|
|
5
5
|
|
|
@@ -26,6 +26,7 @@ export function WorkspaceProjectFilesToolbar({
|
|
|
26
26
|
>
|
|
27
27
|
{rootLabel}
|
|
28
28
|
</span>
|
|
29
|
+
<IconActionGroup>
|
|
29
30
|
<IconActionButton
|
|
30
31
|
icon={<FilePlus2 className="h-4 w-4" />}
|
|
31
32
|
label={t('chatWorkspaceNewFile')}
|
|
@@ -59,6 +60,7 @@ export function WorkspaceProjectFilesToolbar({
|
|
|
59
60
|
size="sm"
|
|
60
61
|
/>
|
|
61
62
|
</ContextMenuTrigger>
|
|
63
|
+
</IconActionGroup>
|
|
62
64
|
</div>
|
|
63
65
|
);
|
|
64
66
|
}
|
|
@@ -83,7 +83,7 @@ function SessionCronJobCard({
|
|
|
83
83
|
const jobLabel = job.name || job.id;
|
|
84
84
|
|
|
85
85
|
return (
|
|
86
|
-
<article className="rounded-2xl border border-border/60 bg-background px-3.5 py-3 shadow-sm transition-colors hover:bg-
|
|
86
|
+
<article className="rounded-2xl border border-border/60 bg-background px-3.5 py-3 shadow-sm transition-colors hover:bg-[var(--interaction-hover)] focus-within:bg-[var(--interaction-hover)]">
|
|
87
87
|
<div className="flex items-start gap-3">
|
|
88
88
|
<span
|
|
89
89
|
className={cn(
|
|
@@ -189,7 +189,7 @@ function SessionCronJobCard({
|
|
|
189
189
|
setMenuOpen(false);
|
|
190
190
|
void cronActions.runJob(job);
|
|
191
191
|
}}
|
|
192
|
-
className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-foreground transition-colors hover:bg-
|
|
192
|
+
className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-foreground transition-colors hover:bg-[var(--interaction-hover)] disabled:cursor-not-allowed disabled:opacity-50"
|
|
193
193
|
>
|
|
194
194
|
<Play className="h-3.5 w-3.5 text-muted-foreground" />
|
|
195
195
|
{t("cronRunNow")}
|
|
@@ -201,7 +201,7 @@ function SessionCronJobCard({
|
|
|
201
201
|
setMenuOpen(false);
|
|
202
202
|
void cronActions.deleteJob(job);
|
|
203
203
|
}}
|
|
204
|
-
className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-red-600 transition-colors hover:bg-
|
|
204
|
+
className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-red-600 transition-colors hover:bg-destructive/10 disabled:cursor-not-allowed disabled:opacity-50"
|
|
205
205
|
>
|
|
206
206
|
{t("delete")}
|
|
207
207
|
</button>
|
|
@@ -105,7 +105,7 @@ function WorkspaceUnsupportedContent({
|
|
|
105
105
|
<a
|
|
106
106
|
href={contentUrl}
|
|
107
107
|
download={label}
|
|
108
|
-
className="inline-flex h-8 items-center rounded-lg border border-border bg-card px-3 text-xs font-medium text-foreground transition-colors hover:bg-
|
|
108
|
+
className="inline-flex h-8 items-center rounded-lg border border-border bg-card px-3 text-xs font-medium text-foreground transition-colors hover:bg-[var(--interaction-hover)]"
|
|
109
109
|
>
|
|
110
110
|
{t("chatWorkspacePreviewDownload")}
|
|
111
111
|
</a>
|
|
@@ -113,7 +113,7 @@ function WorkspaceUnsupportedContent({
|
|
|
113
113
|
href={contentUrl}
|
|
114
114
|
target="_blank"
|
|
115
115
|
rel="noreferrer"
|
|
116
|
-
className="inline-flex h-8 items-center rounded-lg bg-primary px-3 text-xs font-medium text-primary-foreground transition-colors hover:bg-primary
|
|
116
|
+
className="inline-flex h-8 items-center rounded-lg bg-primary px-3 text-xs font-medium text-primary-foreground transition-colors hover:bg-[hsl(var(--primary-hover))]"
|
|
117
117
|
>
|
|
118
118
|
{t("chatWorkspacePreviewOpenExternally")}
|
|
119
119
|
</a>
|
|
@@ -137,7 +137,7 @@ export function WorkspaceMarkdownOutline({
|
|
|
137
137
|
<li key={item.index}>
|
|
138
138
|
<button
|
|
139
139
|
type="button"
|
|
140
|
-
className="block w-full truncate rounded-md py-1.5 pr-2 text-left text-xs leading-4 text-gray-600 transition-colors hover:bg-
|
|
140
|
+
className="block w-full truncate rounded-md py-1.5 pr-2 text-left text-xs leading-4 text-gray-600 transition-colors hover:bg-[var(--interaction-hover)] hover:text-gray-950 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-border active:bg-[var(--interaction-hover)]"
|
|
141
141
|
style={{
|
|
142
142
|
paddingInlineStart: `${0.5 + item.depth * 0.75}rem`,
|
|
143
143
|
}}
|
|
@@ -220,6 +220,7 @@ export function CronConfig() {
|
|
|
220
220
|
return (
|
|
221
221
|
<PageLayout className="space-y-6">
|
|
222
222
|
<PageHeader
|
|
223
|
+
mobileTitleInShell
|
|
223
224
|
headingLevel={1}
|
|
224
225
|
title={t("cronPageTitle")}
|
|
225
226
|
description={t("cronPageDescription")}
|
|
@@ -307,8 +308,8 @@ export function CronConfig() {
|
|
|
307
308
|
handlePageChange(0);
|
|
308
309
|
}}
|
|
309
310
|
className={cn(
|
|
310
|
-
"rounded-lg px-2.5 py-2 text-[11px] font-medium text-muted-foreground transition-colors hover:bg-
|
|
311
|
-
status === value && "bg-
|
|
311
|
+
"rounded-lg px-2.5 py-2 text-[11px] font-medium text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] hover:text-foreground",
|
|
312
|
+
status === value && "bg-[var(--interaction-selection)] hover:bg-[var(--interaction-selection)] text-foreground",
|
|
312
313
|
)}
|
|
313
314
|
>
|
|
314
315
|
{t(label)}
|
|
@@ -206,7 +206,7 @@ export function CronJobDetailDialog({
|
|
|
206
206
|
<SheetFooter className="shrink-0 border-t border-border/60 bg-background px-5 py-4 sm:px-7">
|
|
207
207
|
<Button
|
|
208
208
|
variant="ghost"
|
|
209
|
-
className="text-red-600 hover:bg-
|
|
209
|
+
className="text-red-600 hover:bg-destructive/10 hover:text-red-700"
|
|
210
210
|
onClick={() => onDelete(job)}
|
|
211
211
|
>
|
|
212
212
|
<Trash2 className="mr-2 h-4 w-4" />
|
|
@@ -105,14 +105,14 @@ export function CronJobRow({
|
|
|
105
105
|
return (
|
|
106
106
|
<div
|
|
107
107
|
className={cn(
|
|
108
|
-
"group relative rounded-xl border-b border-border/55 transition-colors duration-150 last:border-b-0 hover:bg-
|
|
108
|
+
"group relative rounded-xl border-b border-border/55 transition-colors duration-150 last:border-b-0 hover:bg-[var(--interaction-hover)] focus-within:bg-[var(--interaction-hover)]",
|
|
109
109
|
expanded && "bg-muted/35",
|
|
110
110
|
)}
|
|
111
111
|
>
|
|
112
|
-
<div className="flex items-center gap-3 px-1 py-3.5">
|
|
112
|
+
<div className="flex flex-wrap items-center gap-3 px-1 py-3.5">
|
|
113
113
|
<button
|
|
114
114
|
type="button"
|
|
115
|
-
className="grid min-w-0 flex-1 grid-cols-[36px_minmax(0,1fr)] items-center gap-3 rounded-lg pr-16 text-left focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
|
|
115
|
+
className="grid min-w-0 flex-1 max-md:basis-full grid-cols-[36px_minmax(0,1fr)] items-center gap-3 rounded-lg md:pr-16 text-left focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
|
|
116
116
|
aria-controls={previewId}
|
|
117
117
|
aria-expanded={expanded}
|
|
118
118
|
aria-label={`${t(expanded ? "cronCollapseTask" : "cronExpandTask")} ${jobLabel}`}
|
|
@@ -159,14 +159,14 @@ export function CronJobRow({
|
|
|
159
159
|
</button>
|
|
160
160
|
|
|
161
161
|
<TooltipProvider delayDuration={250}>
|
|
162
|
-
<div className="relative flex shrink-0 items-center gap-1">
|
|
162
|
+
<div className="relative flex shrink-0 items-center gap-1 max-md:ml-auto">
|
|
163
163
|
<Switch
|
|
164
164
|
checked={job.enabled}
|
|
165
165
|
onCheckedChange={(checked) => onToggle(job, checked)}
|
|
166
166
|
aria-label={job.enabled ? t("cronDisable") : t("cronEnable")}
|
|
167
167
|
/>
|
|
168
168
|
|
|
169
|
-
<div className="flex items-center gap-0.5 opacity-100 transition-opacity duration-150 [@media(hover:hover)]:pointer-events-none [@media(hover:hover)]:opacity-0 [@media(hover:hover)]:group-focus-within:pointer-events-auto [@media(hover:hover)]:group-focus-within:opacity-100 [@media(hover:hover)]:group-hover:pointer-events-auto [@media(hover:hover)]:group-hover:opacity-100">
|
|
169
|
+
<div className="flex items-center gap-0.5 opacity-100 transition-opacity duration-150 md:[@media(hover:hover)]:pointer-events-none md:[@media(hover:hover)]:opacity-0 [@media(hover:hover)]:group-focus-within:pointer-events-auto [@media(hover:hover)]:group-focus-within:opacity-100 [@media(hover:hover)]:group-hover:pointer-events-auto [@media(hover:hover)]:group-hover:opacity-100">
|
|
170
170
|
<Tooltip>
|
|
171
171
|
<TooltipTrigger asChild>
|
|
172
172
|
<Button
|
|
@@ -206,7 +206,7 @@ export function CronJobRow({
|
|
|
206
206
|
setMenuOpen(false);
|
|
207
207
|
onRun(job);
|
|
208
208
|
}}
|
|
209
|
-
className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-foreground transition-colors hover:bg-
|
|
209
|
+
className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-foreground transition-colors hover:bg-[var(--interaction-hover)]"
|
|
210
210
|
>
|
|
211
211
|
<Play className="h-3.5 w-3.5 text-muted-foreground" />
|
|
212
212
|
{t("cronRunNow")}
|
|
@@ -217,7 +217,7 @@ export function CronJobRow({
|
|
|
217
217
|
setMenuOpen(false);
|
|
218
218
|
onDelete(job);
|
|
219
219
|
}}
|
|
220
|
-
className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-red-600 transition-colors hover:bg-
|
|
220
|
+
className="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-red-600 transition-colors hover:bg-destructive/10"
|
|
221
221
|
>
|
|
222
222
|
<Trash2 className="h-3.5 w-3.5" />
|
|
223
223
|
{t("delete")}
|