@nextclaw/ui 0.15.1 → 0.15.3
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 +51 -0
- package/dist/assets/{api-b1R9VdeH.js → api-iNBpppzj.js} +3 -3
- package/dist/assets/{appearance-settings-page-D2O9pch9.js → appearance-settings-page-DMffQFR3.js} +1 -1
- package/dist/assets/{book-open-B77lQ2Tg.js → book-open-C3mJGwiy.js} +1 -1
- package/dist/assets/channels-list-page-CCtp0BRS.js +8 -0
- package/dist/assets/chat-page-H5a0dWvO.js +1 -0
- package/dist/assets/config-split-page-CrOJgB-Y.js +1 -0
- package/dist/assets/{confirm-dialog-C-NXSioX.js → confirm-dialog-Chv50USy.js} +2 -2
- package/dist/assets/{desktop-update-config-usHpXugP.js → desktop-update-config-KzTuXRf_.js} +1 -1
- package/dist/assets/{dist-jdGmbb6w.js → dist-BunzmC4B.js} +1 -1
- package/dist/assets/{dist-YtoqU-AT.js → dist-ChmGwvtK.js} +1 -1
- package/dist/assets/doc-browser-DNRL4Zvd.js +1 -0
- package/dist/assets/doc-browser-Dg0pmkOg.js +1 -0
- package/dist/assets/doc-browser-context-BHY-0FSD.js +1 -0
- package/dist/assets/{es2015-bNpL2LKy.js → es2015-DQZ5JWwK.js} +1 -1
- package/dist/assets/{external-link-BM6fk8q-.js → external-link-CU0kzzIP.js} +1 -1
- package/dist/assets/form-actions-BvCp_0lS.js +1 -0
- package/dist/assets/{i18n-provider-CntWolRA.js → i18n-provider-Cu8XyZb_.js} +1 -1
- package/dist/assets/index-CzfBdvK1.css +1 -0
- package/dist/assets/index-DGqHne1Q.js +104 -0
- package/dist/assets/loader-circle-CDSFuzmk.js +1 -0
- package/dist/assets/mcp-marketplace-page-BeEQK0DL.js +9 -0
- package/dist/assets/mcp-marketplace-page-D6idOTLp.js +1 -0
- package/dist/assets/model-config-page-bNNo-XyG.js +1 -0
- package/dist/assets/plus-D4DsdLN-.js +1 -0
- package/dist/assets/{provider-scoped-model-input-Cm_a4GHf.js → provider-scoped-model-input-IlgQCsoT.js} +1 -1
- package/dist/assets/providers-config-page-wLo6CAJw.js +1 -0
- package/dist/assets/{react-BN8uzPnp.js → react-BPIsQIlO.js} +1 -1
- package/dist/assets/{refresh-cw-BpVcFPmJ.js → refresh-cw-CILd1vAP.js} +1 -1
- package/dist/assets/remote-uKEYp7AR.js +1 -0
- package/dist/assets/rotate-cw-wPFPg1kH.js +1 -0
- package/dist/assets/runtime-config-page-DDn1sP4G.js +1 -0
- package/dist/assets/{save-BpFW5fpk.js → save-ByJqcPTP.js} +1 -1
- package/dist/assets/{search-D0uO7enf.js → search-DVIV6pfD.js} +1 -1
- package/dist/assets/search-config-page-B-Cf4iiB.js +1 -0
- package/dist/assets/secrets-config-page-DPKsY8Iw.js +3 -0
- package/dist/assets/security-config-e9SSBlKr.js +1 -0
- package/dist/assets/{select-Bh-CrA4p.js → select-BdgczSNw.js} +1 -1
- package/dist/assets/{setting-row-BJfCHRcb.js → setting-row-BkTVUTKx.js} +1 -1
- package/dist/assets/{settings-2-Blzi1vr6.js → settings-2-CH5shGg_.js} +1 -1
- package/dist/assets/{side-dock-ZdaSrQVB.js → side-dock-BsBvcJ9i.js} +2 -2
- package/dist/assets/{skeleton-BLlEzebZ.js → skeleton-DeX1FKw7.js} +1 -1
- package/dist/assets/switch-Cv8Ekb3x.js +1 -0
- package/dist/assets/{tag-chip-CzGihiQx.js → tag-chip-RB9uKcoC.js} +1 -1
- package/dist/assets/{tooltip-CdcrBjrC.js → tooltip-oQlEN-l6.js} +1 -1
- package/dist/assets/{use-config-CVPgsBmU.js → use-config-l3W7y8Qz.js} +1 -1
- package/dist/assets/{use-confirm-dialog-CSeBk9SF.js → use-confirm-dialog-BAxaVOJI.js} +1 -1
- package/dist/assets/x-BBMffEN0.js +1 -0
- package/dist/index.html +38 -30
- package/index.html +12 -4
- package/package.json +9 -9
- package/src/app/components/layout/__tests__/sidebar.layout.test.tsx +29 -1
- package/src/app/components/layout/sidebar-items.tsx +46 -7
- package/src/app/components/layout/sidebar-rail.styles.ts +2 -2
- package/src/app/components/layout/sidebar.tsx +84 -62
- package/src/app/configs/app-navigation.config.ts +49 -0
- package/src/app/styles/design-system.css +99 -4
- package/src/features/channels/components/config/channel-form.tsx +14 -11
- package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +40 -0
- package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +3 -1
- package/src/features/chat/components/conversation/chat-conversation-panel.tsx +1 -1
- package/src/features/chat/components/layout/__tests__/chat-sidebar-toolbar.test.tsx +48 -0
- package/src/features/chat/components/layout/__tests__/chat-sidebar-utility-menu.test.tsx +55 -0
- package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +0 -3
- package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +3 -4
- package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +30 -31
- package/src/features/chat/components/layout/chat-sidebar.tsx +21 -7
- package/src/features/chat/features/conversation/components/session-conversation-input.tsx +2 -1
- package/src/features/chat/features/conversation/components/session-queued-input-rows.tsx +1 -1
- package/src/features/chat/features/message/components/__tests__/chat-inline-panel-app-card.test.tsx +22 -1
- package/src/features/chat/features/message/components/__tests__/chat-message-list.container.test.tsx +62 -1
- package/src/features/chat/features/message/components/chat-inline-panel-app-card.tsx +10 -5
- package/src/features/chat/features/message/components/chat-message-list.container.tsx +47 -1
- package/src/features/chat/features/message/utils/__tests__/chat-message-process-summary.utils.test.ts +11 -1
- package/src/features/chat/features/message/utils/__tests__/chat-message-texts.utils.test.ts +23 -0
- package/src/features/chat/features/message/utils/chat-inline-panel-app-card.utils.ts +0 -11
- package/src/features/chat/features/message/utils/chat-message-process-summary.utils.ts +5 -0
- package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +138 -0
- package/src/features/chat/features/session/components/__tests__/chat-sidebar-project-groups.test.tsx +116 -0
- package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +108 -46
- package/src/features/chat/features/session/components/chat-sidebar-session-entry.tsx +6 -0
- package/src/features/chat/features/session/components/chat-sidebar-session-item.tsx +48 -24
- package/src/features/chat/features/session/components/chat-sidebar-session-list.tsx +0 -3
- package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +0 -4
- package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx +2 -2
- package/src/features/chat/features/session/utils/chat-sidebar-session-groups.utils.ts +25 -3
- package/src/features/chat/features/welcome/components/chat-welcome-capability-grid.tsx +9 -4
- package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome.tsx +0 -5
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.test.tsx +226 -56
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +1 -0
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel.test.tsx +144 -0
- package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +99 -0
- 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 +4 -2
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +232 -21
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +3 -0
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +44 -1
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel.tsx +45 -3
- package/src/features/chat/features/workspace/utils/chat-workspace-file-tab-persistence.utils.ts +4 -0
- package/src/features/chat/managers/__tests__/chat-session-list.manager.test.ts +33 -2
- package/src/features/chat/managers/chat-session-list.manager.ts +32 -0
- package/src/features/chat/managers/chat-thread.manager.ts +2 -0
- package/src/features/chat/stores/chat-session-list.store.ts +28 -5
- package/src/features/chat/stores/chat-thread.store.ts +3 -0
- package/src/features/cron/components/cron-config.tsx +63 -80
- package/src/features/marketplace/components/detail-doc/__tests__/marketplace-detail-doc.test.tsx +44 -6
- package/src/features/marketplace/components/marketplace-detail-doc.tsx +8 -4
- package/src/features/marketplace/components/marketplace-page-parts.tsx +1 -1
- package/src/features/marketplace/components/mcp/mcp-marketplace-page.tsx +5 -12
- package/src/features/marketplace/hooks/use-marketplace-detail-doc-entry.ts +84 -0
- package/src/features/panel-apps/components/panel-app-list-item.tsx +6 -6
- package/src/features/panel-apps/components/panel-apps-list.tsx +2 -2
- package/src/features/panel-apps/index.ts +1 -0
- package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +2 -10
- package/src/features/panel-apps/utils/panel-app-iframe.utils.ts +6 -0
- package/src/features/pwa/managers/__tests__/pwa-shell-theme.manager.test.ts +11 -3
- package/src/features/pwa/managers/pwa-shell-theme.manager.ts +3 -1
- package/src/features/right-panel-resources/components/right-panel-resource-home-page.tsx +1 -1
- package/src/features/service-apps/components/service-apps-panel.tsx +145 -35
- package/src/features/settings/components/config/provider-auth-section.tsx +1 -1
- package/src/features/settings/components/config/provider-form.tsx +11 -8
- package/src/features/settings/components/config/provider-models-section.tsx +7 -7
- package/src/features/settings/components/config/provider-pill-selector.tsx +1 -1
- package/src/features/settings/components/config/secrets-config-form.tsx +5 -4
- package/src/features/settings/pages/model-config-page.tsx +26 -25
- package/src/features/settings/pages/providers-config-page.tsx +10 -13
- package/src/features/settings/pages/search-config-page.tsx +8 -5
- package/src/features/side-dock/components/side-dock.tsx +3 -3
- package/src/features/system-status/components/config/runtime-config-editor.tsx +5 -4
- package/src/index.css +257 -13
- package/src/shared/components/actions/action-link.tsx +1 -1
- package/src/shared/components/config-split-page.tsx +6 -6
- package/src/shared/components/doc-browser/__tests__/doc-browser-url.utils.test.ts +73 -0
- package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +48 -0
- package/src/shared/components/doc-browser/doc-browser-context.tsx +4 -0
- package/src/shared/components/doc-browser/doc-browser-panel-parts.tsx +6 -2
- package/src/shared/components/doc-browser/doc-browser-renderer.types.ts +2 -1
- package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +10 -10
- package/src/shared/components/doc-browser/doc-browser.tsx +6 -4
- package/src/shared/components/doc-browser/utils/doc-browser-url.utils.ts +62 -4
- package/src/shared/components/resizable-right-panel/__tests__/resizable-right-panel.test.tsx +18 -0
- package/src/shared/components/resizable-right-panel/resizable-right-panel.tsx +28 -3
- package/src/shared/components/ui/actions/__tests__/icon-action-button.test.tsx +36 -0
- package/src/shared/components/ui/actions/form-actions.tsx +25 -0
- package/src/shared/components/ui/actions/icon-action-button.tsx +25 -2
- package/src/shared/components/ui/button.tsx +1 -1
- package/src/shared/components/ui/card.tsx +12 -4
- package/src/shared/components/ui/dialog.tsx +1 -1
- package/src/shared/components/ui/input.tsx +1 -1
- package/src/shared/components/ui/select.tsx +1 -1
- package/src/shared/components/ui/switch.tsx +1 -1
- package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +2 -1
- package/src/shared/components/ui/tabs.tsx +1 -1
- package/src/shared/components/ui/textarea.tsx +1 -1
- package/src/shared/hooks/use-server-path-browse.ts +26 -4
- package/src/shared/hooks/use-server-path-read.ts +11 -1
- package/src/shared/lib/api/utils/server-path.utils.ts +1 -0
- package/src/shared/lib/i18n/locales/en-US/chat.json +99 -0
- package/src/shared/lib/i18n/locales/en-US/core.json +3 -0
- package/src/shared/lib/i18n/locales/en-US/doc-browser.json +5 -0
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +99 -0
- package/src/shared/lib/i18n/locales/zh-CN/core.json +3 -0
- package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +5 -0
- package/src/shared/lib/session-project/workspace-file-breadcrumb.utils.ts +9 -5
- package/src/shared/lib/theme/index.test.ts +21 -0
- package/src/shared/lib/theme/index.ts +6 -4
- package/src/vite-env.d.ts +2 -0
- package/dist/assets/channels-list-page-DcsIQc6A.js +0 -8
- package/dist/assets/chat-page-CZ7WxPir.js +0 -1
- package/dist/assets/config-split-page-BWQ6_Raq.js +0 -1
- package/dist/assets/doc-browser-B_Tf9n70.js +0 -1
- package/dist/assets/doc-browser-BdZPFOVa.js +0 -1
- package/dist/assets/doc-browser-context-DwokemUn.js +0 -1
- package/dist/assets/index-BIcEw90u.js +0 -104
- package/dist/assets/index-BiNSTKTU.css +0 -1
- package/dist/assets/loader-circle-MBgNSVIH.js +0 -1
- package/dist/assets/mcp-marketplace-page-CLmUstLN.js +0 -9
- package/dist/assets/mcp-marketplace-page-rZkmWPMy.js +0 -1
- package/dist/assets/model-config-page-Di0ySJD2.js +0 -1
- package/dist/assets/plus-vDqW5Kxp.js +0 -1
- package/dist/assets/providers-config-page-BAf2W0MV.js +0 -1
- package/dist/assets/remote-CLQ0IBM8.js +0 -1
- package/dist/assets/rotate-cw-CvNBv7_w.js +0 -1
- package/dist/assets/runtime-config-page-CflvvoDc.js +0 -1
- package/dist/assets/search-config-page-D0klFUXd.js +0 -1
- package/dist/assets/secrets-config-page-dVZ631Wp.js +0 -3
- package/dist/assets/security-config-C5gnlkuj.js +0 -1
- package/dist/assets/switch-CFLJFNSd.js +0 -1
- package/dist/assets/x-BF2KQ--V.js +0 -1
- /package/dist/assets/{config-hints-fGnUjDe9.js → config-hints-C_iP1zl_.js} +0 -0
|
@@ -7,7 +7,7 @@ import { type SessionContextView } from '@/features/chat/features/session/utils/
|
|
|
7
7
|
import type { SessionRunStatus } from '@/features/chat/types/session-run-status.types';
|
|
8
8
|
import { cn } from '@/shared/lib/utils';
|
|
9
9
|
import { t } from '@/shared/lib/i18n';
|
|
10
|
-
import { Check, GitBranch, Pencil, X } from 'lucide-react';
|
|
10
|
+
import { Check, GitBranch, Pencil, Pin, X } from 'lucide-react';
|
|
11
11
|
|
|
12
12
|
type ChatSidebarSessionItemProps = {
|
|
13
13
|
sessionKey: string;
|
|
@@ -15,6 +15,7 @@ type ChatSidebarSessionItemProps = {
|
|
|
15
15
|
showUnreadDot: boolean;
|
|
16
16
|
runStatus?: SessionRunStatus;
|
|
17
17
|
context: SessionContextView;
|
|
18
|
+
isPinned: boolean;
|
|
18
19
|
title: string;
|
|
19
20
|
previewText: string;
|
|
20
21
|
trailingText: string;
|
|
@@ -31,6 +32,7 @@ type ChatSidebarSessionItemProps = {
|
|
|
31
32
|
onDraftLabelChange: (value: string) => void;
|
|
32
33
|
onSave: () => void | Promise<void>;
|
|
33
34
|
onCancel: () => void;
|
|
35
|
+
onTogglePinned: () => void;
|
|
34
36
|
};
|
|
35
37
|
|
|
36
38
|
type ChatSidebarSessionEditingViewProps = Pick<
|
|
@@ -72,7 +74,6 @@ function ChatSidebarSessionEditingView({
|
|
|
72
74
|
icon={<Check className="h-3.5 w-3.5" />}
|
|
73
75
|
label={t('save')}
|
|
74
76
|
tooltip={false}
|
|
75
|
-
className="h-7 w-7 rounded-lg text-gray-500 hover:bg-white hover:text-gray-900"
|
|
76
77
|
onClick={() => void onSave()}
|
|
77
78
|
disabled={isSaving}
|
|
78
79
|
/>
|
|
@@ -80,7 +81,6 @@ function ChatSidebarSessionEditingView({
|
|
|
80
81
|
icon={<X className="h-3.5 w-3.5" />}
|
|
81
82
|
label={t('cancel')}
|
|
82
83
|
tooltip={false}
|
|
83
|
-
className="h-7 w-7 rounded-lg text-gray-500 hover:bg-white hover:text-gray-900"
|
|
84
84
|
onClick={onCancel}
|
|
85
85
|
disabled={isSaving}
|
|
86
86
|
/>
|
|
@@ -100,6 +100,7 @@ function ChatSidebarSessionDisplayView({
|
|
|
100
100
|
showUnreadDot,
|
|
101
101
|
runStatus,
|
|
102
102
|
context,
|
|
103
|
+
isPinned,
|
|
103
104
|
title,
|
|
104
105
|
previewText,
|
|
105
106
|
trailingText,
|
|
@@ -109,14 +110,15 @@ function ChatSidebarSessionDisplayView({
|
|
|
109
110
|
childSessionCount = 0,
|
|
110
111
|
onSelect,
|
|
111
112
|
onOpenChildSessions,
|
|
112
|
-
onStartEditing
|
|
113
|
+
onStartEditing,
|
|
114
|
+
onTogglePinned
|
|
113
115
|
}: ChatSidebarSessionDisplayViewProps) {
|
|
114
|
-
const trailingControlsClassName = childSessionCount > 0 && onOpenChildSessions ? 'pr-
|
|
116
|
+
const trailingControlsClassName = childSessionCount > 0 && onOpenChildSessions ? 'pr-20' : 'pr-12';
|
|
115
117
|
|
|
116
118
|
return (
|
|
117
119
|
<div className="group/session relative">
|
|
118
120
|
<button type="button" onClick={onSelect} className="w-full text-left">
|
|
119
|
-
<div className={cn('flex min-w-0 items-
|
|
121
|
+
<div className={cn('flex min-h-6 min-w-0 items-center', trailingControlsClassName)}>
|
|
120
122
|
<span className="flex min-w-0 items-center gap-1.5">
|
|
121
123
|
{agentId?.trim() && agentId.trim().toLowerCase() !== 'main' ? (
|
|
122
124
|
<AgentAvatar
|
|
@@ -126,7 +128,7 @@ function ChatSidebarSessionDisplayView({
|
|
|
126
128
|
className="h-5 w-5 shrink-0"
|
|
127
129
|
/>
|
|
128
130
|
) : null}
|
|
129
|
-
<span className="truncate font-medium">{title}</span>
|
|
131
|
+
<span className="truncate leading-6 font-medium">{title}</span>
|
|
130
132
|
{context.label ? (
|
|
131
133
|
<span
|
|
132
134
|
className={cn(
|
|
@@ -140,7 +142,7 @@ function ChatSidebarSessionDisplayView({
|
|
|
140
142
|
</span>
|
|
141
143
|
) : null}
|
|
142
144
|
{context.icon ? (
|
|
143
|
-
<span className="inline-flex h-
|
|
145
|
+
<span className="inline-flex h-5 w-5 shrink-0 items-center justify-center">
|
|
144
146
|
<SessionContextIconNode icon={context.icon} className={active ? 'text-gray-700' : 'text-gray-500'} />
|
|
145
147
|
</span>
|
|
146
148
|
) : null}
|
|
@@ -168,7 +170,7 @@ function ChatSidebarSessionDisplayView({
|
|
|
168
170
|
onOpenChildSessions();
|
|
169
171
|
}}
|
|
170
172
|
className={cn(
|
|
171
|
-
'absolute right-
|
|
173
|
+
'absolute right-12 top-0 inline-flex h-6 items-center gap-1 rounded-md px-1.5 text-[10px] font-medium text-muted-foreground transition-colors hover:bg-black/10 hover:text-foreground',
|
|
172
174
|
active
|
|
173
175
|
? 'opacity-100'
|
|
174
176
|
: 'opacity-0 group-hover/session:opacity-100 group-focus-within/session:opacity-100'
|
|
@@ -181,23 +183,41 @@ function ChatSidebarSessionDisplayView({
|
|
|
181
183
|
</button>
|
|
182
184
|
) : null}
|
|
183
185
|
{runStatus ? (
|
|
184
|
-
<span className="absolute right-0 top-0 inline-flex h-
|
|
186
|
+
<span className="absolute right-0 top-0 inline-flex h-6 w-6 items-center justify-center transition-opacity group-hover/session:opacity-0 group-focus-within/session:opacity-0">
|
|
185
187
|
<SessionRunBadge status={runStatus} />
|
|
186
188
|
</span>
|
|
187
189
|
) : null}
|
|
188
|
-
<
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
190
|
+
<div className="absolute right-0 top-0 flex h-6 items-center gap-0.5 opacity-0 transition-opacity group-hover/session:opacity-100 group-focus-within/session:opacity-100">
|
|
191
|
+
<IconActionButton
|
|
192
|
+
size="sm"
|
|
193
|
+
tone="strong"
|
|
194
|
+
icon={
|
|
195
|
+
<Pin
|
|
196
|
+
className={cn(
|
|
197
|
+
'h-3.5 w-3.5',
|
|
198
|
+
isPinned && 'fill-current text-foreground',
|
|
199
|
+
)}
|
|
200
|
+
/>
|
|
201
|
+
}
|
|
202
|
+
label={t(isPinned ? 'chatSidebarUnpinSession' : 'chatSidebarPinSession')}
|
|
203
|
+
tooltipSide="right"
|
|
204
|
+
onClick={(event) => {
|
|
205
|
+
event.stopPropagation();
|
|
206
|
+
onTogglePinned();
|
|
207
|
+
}}
|
|
208
|
+
/>
|
|
209
|
+
<IconActionButton
|
|
210
|
+
size="sm"
|
|
211
|
+
tone="strong"
|
|
212
|
+
icon={<Pencil className="h-3.5 w-3.5" />}
|
|
213
|
+
label={t('edit')}
|
|
214
|
+
tooltipSide="right"
|
|
215
|
+
onClick={(event) => {
|
|
216
|
+
event.stopPropagation();
|
|
217
|
+
onStartEditing();
|
|
218
|
+
}}
|
|
219
|
+
/>
|
|
220
|
+
</div>
|
|
201
221
|
</div>
|
|
202
222
|
);
|
|
203
223
|
}
|
|
@@ -208,6 +228,7 @@ export function ChatSidebarSessionItem({
|
|
|
208
228
|
showUnreadDot,
|
|
209
229
|
runStatus,
|
|
210
230
|
context,
|
|
231
|
+
isPinned,
|
|
211
232
|
title,
|
|
212
233
|
previewText,
|
|
213
234
|
trailingText,
|
|
@@ -223,7 +244,8 @@ export function ChatSidebarSessionItem({
|
|
|
223
244
|
onStartEditing,
|
|
224
245
|
onDraftLabelChange,
|
|
225
246
|
onSave,
|
|
226
|
-
onCancel
|
|
247
|
+
onCancel,
|
|
248
|
+
onTogglePinned
|
|
227
249
|
}: ChatSidebarSessionItemProps) {
|
|
228
250
|
return (
|
|
229
251
|
<div
|
|
@@ -249,6 +271,7 @@ export function ChatSidebarSessionItem({
|
|
|
249
271
|
showUnreadDot={showUnreadDot}
|
|
250
272
|
runStatus={runStatus}
|
|
251
273
|
context={context}
|
|
274
|
+
isPinned={isPinned}
|
|
252
275
|
title={title}
|
|
253
276
|
previewText={previewText}
|
|
254
277
|
trailingText={trailingText}
|
|
@@ -259,6 +282,7 @@ export function ChatSidebarSessionItem({
|
|
|
259
282
|
childSessionCount={childSessionCount}
|
|
260
283
|
onOpenChildSessions={onOpenChildSessions}
|
|
261
284
|
onStartEditing={onStartEditing}
|
|
285
|
+
onTogglePinned={onTogglePinned}
|
|
262
286
|
/>
|
|
263
287
|
)}
|
|
264
288
|
</div>
|
|
@@ -19,7 +19,6 @@ type ChatSidebarSessionListProps = {
|
|
|
19
19
|
defaultSessionType: string;
|
|
20
20
|
sessionTypeOptions: SessionTypeOption[];
|
|
21
21
|
renderSessionItem: (item: NcpSessionListItemView) => ReactNode;
|
|
22
|
-
onCreateSession: (sessionType: string, projectRoot?: string | null) => void;
|
|
23
22
|
};
|
|
24
23
|
|
|
25
24
|
function ChatSidebarEmptyState({ label }: { label: string }) {
|
|
@@ -36,7 +35,6 @@ export function ChatSidebarSessionList({
|
|
|
36
35
|
groups,
|
|
37
36
|
isLoading,
|
|
38
37
|
isProjectFirstView,
|
|
39
|
-
onCreateSession,
|
|
40
38
|
projectGroups,
|
|
41
39
|
renderSessionItem,
|
|
42
40
|
sessionTypeOptions,
|
|
@@ -54,7 +52,6 @@ export function ChatSidebarSessionList({
|
|
|
54
52
|
defaultSessionType={defaultSessionType}
|
|
55
53
|
sessionTypeOptions={sessionTypeOptions}
|
|
56
54
|
renderSessionItem={renderSessionItem}
|
|
57
|
-
onCreateSession={onCreateSession}
|
|
58
55
|
/>
|
|
59
56
|
);
|
|
60
57
|
}
|
package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx
CHANGED
|
@@ -9,7 +9,6 @@ import { ChatSessionProjectDialog } from './chat-session-project-dialog';
|
|
|
9
9
|
import { t } from '@/shared/lib/i18n';
|
|
10
10
|
|
|
11
11
|
const SESSION_HEADER_ACTION_GROUP_CLASS = 'flex shrink-0 items-center gap-1.5';
|
|
12
|
-
const SESSION_HEADER_ACTION_BUTTON_CLASS = 'h-7 w-7 shrink-0 rounded-lg text-muted-foreground/70 hover:bg-accent hover:text-accent-foreground';
|
|
13
12
|
|
|
14
13
|
type ChatSessionHeaderActionsProps = {
|
|
15
14
|
sessionKey: string;
|
|
@@ -65,7 +64,6 @@ export function ChatSessionHeaderActions({
|
|
|
65
64
|
<IconActionButton
|
|
66
65
|
icon={<GitBranch className="h-4 w-4" />}
|
|
67
66
|
label={t('chatSessionOpenChildSessions')}
|
|
68
|
-
className={SESSION_HEADER_ACTION_BUTTON_CLASS}
|
|
69
67
|
onClick={onOpenChildSessions}
|
|
70
68
|
disabled={isBusy}
|
|
71
69
|
/>
|
|
@@ -74,7 +72,6 @@ export function ChatSessionHeaderActions({
|
|
|
74
72
|
<IconActionButton
|
|
75
73
|
icon={<AlarmClock className="h-4 w-4" />}
|
|
76
74
|
label={t('chatSessionOpenCronJobs')}
|
|
77
|
-
className={SESSION_HEADER_ACTION_BUTTON_CLASS}
|
|
78
75
|
onClick={onOpenSessionCronJobs}
|
|
79
76
|
disabled={isBusy}
|
|
80
77
|
/>
|
|
@@ -85,7 +82,6 @@ export function ChatSessionHeaderActions({
|
|
|
85
82
|
icon={<MoreVertical className="h-4 w-4" />}
|
|
86
83
|
label={t('chatSessionMoreActions')}
|
|
87
84
|
tooltip={false}
|
|
88
|
-
className={SESSION_HEADER_ACTION_BUTTON_CLASS}
|
|
89
85
|
disabled={isBusy}
|
|
90
86
|
/>
|
|
91
87
|
</PopoverTrigger>
|
package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx
CHANGED
|
@@ -40,7 +40,7 @@ import { t } from "@/shared/lib/i18n";
|
|
|
40
40
|
import { cn } from "@/shared/lib/utils";
|
|
41
41
|
|
|
42
42
|
const SWITCHER_TRIGGER_CLASS =
|
|
43
|
-
"group inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-md px-1.5 py-1 text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-
|
|
43
|
+
"group inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-md px-1.5 py-1 text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border";
|
|
44
44
|
|
|
45
45
|
function ChatSessionTitle({ title }: { title: string }) {
|
|
46
46
|
return (
|
|
@@ -111,7 +111,7 @@ function ChatSessionSwitchItem({
|
|
|
111
111
|
type="button"
|
|
112
112
|
aria-current={active ? "page" : undefined}
|
|
113
113
|
className={cn(
|
|
114
|
-
"flex w-full min-w-0 items-start gap-2 rounded-lg px-2.5 py-2 text-left transition-colors focus-visible:outline-none focus-visible:ring-
|
|
114
|
+
"flex w-full min-w-0 items-start gap-2 rounded-lg px-2.5 py-2 text-left transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border",
|
|
115
115
|
active
|
|
116
116
|
? "bg-accent text-accent-foreground"
|
|
117
117
|
: "text-popover-foreground hover:bg-accent/70",
|
|
@@ -13,6 +13,7 @@ export type ChatSidebarProjectGroup = {
|
|
|
13
13
|
projectName: string;
|
|
14
14
|
items: NcpSessionListItemView[];
|
|
15
15
|
latestUpdatedAt: number;
|
|
16
|
+
isPinned: boolean;
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
export function getSessionActivityAtTimestamp(
|
|
@@ -33,8 +34,19 @@ export function sortSessionItemsByActivityAtDesc(
|
|
|
33
34
|
);
|
|
34
35
|
}
|
|
35
36
|
|
|
37
|
+
function sortSessionItemsByPinnedActivityAtDesc(
|
|
38
|
+
items: NcpSessionListItemView[],
|
|
39
|
+
pinnedSessionKeys: ReadonlySet<string>,
|
|
40
|
+
): NcpSessionListItemView[] {
|
|
41
|
+
return [...items].sort((left, right) => {
|
|
42
|
+
const pinnedDifference = Number(pinnedSessionKeys.has(right.session.key)) - Number(pinnedSessionKeys.has(left.session.key));
|
|
43
|
+
return pinnedDifference || getSessionActivityAtTimestamp(right) - getSessionActivityAtTimestamp(left);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
36
47
|
export function groupSessionsByDate(
|
|
37
48
|
items: NcpSessionListItemView[],
|
|
49
|
+
pinnedSessionKeys: ReadonlySet<string> = new Set(),
|
|
38
50
|
): ChatSidebarDateGroup[] {
|
|
39
51
|
const now = new Date();
|
|
40
52
|
const todayStart = new Date(
|
|
@@ -50,7 +62,13 @@ export function groupSessionsByDate(
|
|
|
50
62
|
const previous7: NcpSessionListItemView[] = [];
|
|
51
63
|
const older: NcpSessionListItemView[] = [];
|
|
52
64
|
|
|
53
|
-
|
|
65
|
+
const unpinnedItems = items.filter((item) => !pinnedSessionKeys.has(item.session.key));
|
|
66
|
+
const pinnedItems = sortSessionItemsByPinnedActivityAtDesc(
|
|
67
|
+
items.filter((item) => pinnedSessionKeys.has(item.session.key)),
|
|
68
|
+
pinnedSessionKeys,
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
for (const item of unpinnedItems) {
|
|
54
72
|
const ts = getSessionActivityAtTimestamp(item);
|
|
55
73
|
if (ts >= todayStart) {
|
|
56
74
|
today.push(item);
|
|
@@ -64,6 +82,7 @@ export function groupSessionsByDate(
|
|
|
64
82
|
}
|
|
65
83
|
|
|
66
84
|
const groups: ChatSidebarDateGroup[] = [];
|
|
85
|
+
if (pinnedItems.length > 0) groups.push({ label: t("chatSidebarPinned"), items: pinnedItems });
|
|
67
86
|
if (today.length > 0) groups.push({ label: t("chatSidebarToday"), items: today });
|
|
68
87
|
if (yesterday.length > 0)
|
|
69
88
|
groups.push({ label: t("chatSidebarYesterday"), items: yesterday });
|
|
@@ -75,6 +94,8 @@ export function groupSessionsByDate(
|
|
|
75
94
|
|
|
76
95
|
export function groupSessionsByProject(
|
|
77
96
|
items: NcpSessionListItemView[],
|
|
97
|
+
pinnedSessionKeys: ReadonlySet<string> = new Set(),
|
|
98
|
+
pinnedProjectRoots: ReadonlySet<string> = new Set(),
|
|
78
99
|
): ChatSidebarProjectGroup[] {
|
|
79
100
|
const grouped = new Map<string, ChatSidebarProjectGroup>();
|
|
80
101
|
|
|
@@ -101,15 +122,16 @@ export function groupSessionsByProject(
|
|
|
101
122
|
projectRoot,
|
|
102
123
|
items: [item],
|
|
103
124
|
latestUpdatedAt: updatedAt,
|
|
125
|
+
isPinned: pinnedProjectRoots.has(projectRoot),
|
|
104
126
|
});
|
|
105
127
|
}
|
|
106
128
|
|
|
107
129
|
return [...grouped.values()]
|
|
108
130
|
.map((group) => ({
|
|
109
131
|
...group,
|
|
110
|
-
items:
|
|
132
|
+
items: sortSessionItemsByPinnedActivityAtDesc(group.items, pinnedSessionKeys),
|
|
111
133
|
}))
|
|
112
|
-
.sort((left, right) => right.latestUpdatedAt - left.latestUpdatedAt);
|
|
134
|
+
.sort((left, right) => Number(right.isPinned) - Number(left.isPinned) || right.latestUpdatedAt - left.latestUpdatedAt);
|
|
113
135
|
}
|
|
114
136
|
|
|
115
137
|
export function groupChildSessionsByParentKey(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AlarmClock, BrainCircuit, MessageCircle } from 'lucide-react';
|
|
2
|
+
import { cn } from '@/shared/lib/utils';
|
|
2
3
|
import { t } from '@/shared/lib/i18n';
|
|
3
4
|
|
|
4
5
|
const WELCOME_CAPABILITIES = [
|
|
@@ -34,13 +35,17 @@ export function ChatWelcomeCapabilityGrid({
|
|
|
34
35
|
return (
|
|
35
36
|
<button
|
|
36
37
|
key={capability.titleKey}
|
|
38
|
+
type="button"
|
|
37
39
|
onClick={() => onSelectPrompt(t(capability.promptKey))}
|
|
38
|
-
className=
|
|
40
|
+
className={cn(
|
|
41
|
+
'min-w-0 rounded-xl border border-border/75 bg-card p-3 text-left text-card-foreground shadow-none transition-colors sm:p-3.5',
|
|
42
|
+
'hover:bg-muted/40',
|
|
43
|
+
)}
|
|
39
44
|
>
|
|
40
|
-
<div className="mb-
|
|
41
|
-
<Icon className="h-4
|
|
45
|
+
<div className="mb-2.5 flex h-8 w-8 items-center justify-center rounded-lg bg-muted text-muted-foreground">
|
|
46
|
+
<Icon className="h-4 w-4" />
|
|
42
47
|
</div>
|
|
43
|
-
<div className="mb-1 text-sm font-
|
|
48
|
+
<div className="mb-1 text-sm font-medium text-foreground">
|
|
44
49
|
{t(capability.titleKey)}
|
|
45
50
|
</div>
|
|
46
51
|
<div className="text-[11px] leading-relaxed text-muted-foreground">
|
|
@@ -49,7 +49,7 @@ export function ChatWelcomeProjectPicker({
|
|
|
49
49
|
<PopoverTrigger asChild>
|
|
50
50
|
<button
|
|
51
51
|
type="button"
|
|
52
|
-
className="inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-
|
|
52
|
+
className="inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
|
|
53
53
|
title={projectRoot ?? undefined}
|
|
54
54
|
aria-label={t('chatWelcomeProjectPickerLabel')}
|
|
55
55
|
disabled={!selectable || isSaving}
|
|
@@ -39,7 +39,7 @@ export function ChatWelcomeSessionTypePicker({
|
|
|
39
39
|
<PopoverTrigger asChild>
|
|
40
40
|
<button
|
|
41
41
|
type="button"
|
|
42
|
-
className="inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-
|
|
42
|
+
className="inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
|
|
43
43
|
aria-label={t('chatWelcomeSessionTypePickerLabel')}
|
|
44
44
|
>
|
|
45
45
|
{selectedOption.icon?.src ? (
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
-
import { Bot } from 'lucide-react';
|
|
4
3
|
import { ChatSessionProjectDialog } from '@/features/chat/features/session/components/session-header/chat-session-project-dialog';
|
|
5
4
|
import { ChatWelcomeAgentPicker } from '@/features/chat/features/welcome/components/chat-welcome-agent-picker';
|
|
6
5
|
import { ChatWelcomeCapabilityGrid } from '@/features/chat/features/welcome/components/chat-welcome-capability-grid';
|
|
@@ -64,10 +63,6 @@ export function ChatWelcome({
|
|
|
64
63
|
return (
|
|
65
64
|
<div className="flex min-h-full items-center justify-center px-4 py-8 sm:p-8">
|
|
66
65
|
<div className="min-w-0 w-full max-w-[min(760px,100%)]">
|
|
67
|
-
<div className="mx-auto mb-5 flex h-14 w-14 items-center justify-center rounded-2xl border border-border bg-accent shadow-card">
|
|
68
|
-
<Bot className="h-8 w-8 text-primary" />
|
|
69
|
-
</div>
|
|
70
|
-
|
|
71
66
|
<div className="text-center">
|
|
72
67
|
<h2 className="text-2xl font-semibold text-foreground sm:text-3xl">
|
|
73
68
|
{t('chatWelcomeTitle')}
|