@nextclaw/ui 0.14.1 → 0.14.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 +41 -0
- package/dist/assets/{api-DPcvCLfa.js → api-BP_8IaxB.js} +7 -7
- package/dist/assets/channels-list-page-DEh5Jjqx.js +8 -0
- package/dist/assets/chat-page-BRB0N5WW.js +105 -0
- package/dist/assets/config-split-page-CRhlZ_pH.js +1 -0
- package/dist/assets/{confirm-dialog-CWh5FfK2.js → confirm-dialog-DsivFJ4r.js} +2 -2
- package/dist/assets/{desktop-update-config-DsRhBizi.js → desktop-update-config-B0w9p2ep.js} +1 -1
- package/dist/assets/{dist-DPrgcEC0.js → dist-CikkhOlq.js} +1 -1
- package/dist/assets/{dist-DsE4OsSS.js → dist-PVA_xL1D.js} +1 -1
- package/dist/assets/doc-browser-BoNJ7-tE.js +1 -0
- package/dist/assets/doc-browser-CdJ_d4ik.js +1 -0
- package/dist/assets/doc-browser-context-MTw4EvKd.js +1 -0
- package/dist/assets/{ellipsis-B81FStLm.js → ellipsis-y6vDtq4M.js} +1 -1
- package/dist/assets/{external-link-C_dmG-WJ.js → external-link-DVJIQf_G.js} +1 -1
- package/dist/assets/index-BiE-K8-q.css +1 -0
- package/dist/assets/index-D9BAE_L_.js +105 -0
- package/dist/assets/mcp-marketplace-page-B1SZNY5m.js +40 -0
- package/dist/assets/mcp-marketplace-page-Cq_Tw42T.js +1 -0
- package/dist/assets/middleware-CkFT3R4v.js +1 -0
- package/dist/assets/model-config-page-DotaTUHb.js +1 -0
- package/dist/assets/plus-BbZqquJe.js +1 -0
- package/dist/assets/provider-scoped-model-input-DsFRuWJH.js +1 -0
- package/dist/assets/providers-config-page-DW4tQSLN.js +1 -0
- package/dist/assets/{react-sZz5HSCm.js → react-VNqT5Zp7.js} +1 -1
- package/dist/assets/remote-B8TiUfwW.js +1 -0
- package/dist/assets/rotate-cw-DjHDTkCv.js +1 -0
- package/dist/assets/runtime-config-page-S6ErRHR8.js +1 -0
- package/dist/assets/{save-MzjoiHri.js → save-BOJ477H-.js} +1 -1
- package/dist/assets/{search-B29dE4GN.js → search-BEti5beA.js} +1 -1
- package/dist/assets/{search-config-page-Dl5sZzob.js → search-config-page-DGj5am03.js} +1 -1
- package/dist/assets/{secrets-config-page-C_l-IFCK.js → secrets-config-page--IzrIOid.js} +2 -2
- package/dist/assets/{select-BKmh05hd.js → select-hoj8dK4K.js} +2 -2
- package/dist/assets/{tag-chip-BS_7Ueom.js → tag-chip-T8-h-die.js} +1 -1
- package/dist/assets/use-config-CjRV2hwL.js +1 -0
- package/dist/assets/x-D9PXs_xP.js +1 -0
- package/dist/index.html +70 -19
- package/index.html +55 -5
- package/package.json +9 -9
- package/src/app/components/app-presenter-provider.tsx +11 -2
- package/src/app/components/layout/__tests__/app-layout.test.tsx +11 -2
- package/src/app/components/layout/__tests__/sidebar.layout.test.tsx +110 -79
- package/src/app/components/layout/app-layout.tsx +18 -4
- package/src/app/components/layout/header.tsx +3 -3
- package/src/app/components/layout/page-layout.tsx +2 -2
- package/src/app/components/layout/runtime-status-entry.tsx +7 -7
- package/src/app/components/layout/sidebar-items.tsx +194 -71
- package/src/app/components/layout/sidebar-rail.styles.ts +15 -0
- package/src/app/components/layout/sidebar.tsx +340 -83
- package/src/app/managers/viewport-layout.manager.ts +10 -0
- package/src/app/stores/viewport-layout.store.ts +39 -3
- package/src/app/styles/design-system.css +388 -26
- package/src/app/test/vitest-setup.ts +31 -0
- package/src/features/agents/components/__tests__/agents-page.test.tsx +62 -39
- package/src/features/agents/components/agents-page.tsx +10 -6
- package/src/features/chat/components/chat-sidebar-list-mode-switch.tsx +3 -3
- package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +145 -0
- package/src/features/chat/components/conversation/__tests__/chat-conversation-header.test.tsx +4 -2
- package/src/features/chat/components/conversation/__tests__/chat-conversation-panel.test.tsx +69 -762
- package/src/features/chat/components/conversation/__tests__/chat-conversation-workspace-section.test.tsx +132 -0
- package/src/features/chat/components/conversation/chat-conversation-content.tsx +22 -15
- package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +15 -16
- package/src/features/chat/components/conversation/chat-conversation-header.tsx +7 -6
- package/src/features/chat/components/conversation/chat-conversation-panel.tsx +19 -19
- package/src/features/chat/components/conversation/chat-conversation-skeleton.tsx +13 -13
- package/src/features/chat/components/conversation/chat-conversation-workspace-section.tsx +10 -4
- package/src/features/chat/components/layout/__tests__/chat-sidebar-read-state.test.tsx +52 -11
- package/src/features/chat/components/layout/__tests__/chat-sidebar.test.tsx +18 -16
- package/src/features/chat/components/layout/chat-page-shell.tsx +1 -1
- package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +247 -0
- package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +93 -20
- package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +93 -36
- package/src/features/chat/components/layout/chat-sidebar.tsx +60 -93
- package/src/features/chat/components/providers/chat-presenter.provider.tsx +0 -6
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +225 -0
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +199 -0
- package/src/features/chat/features/conversation/components/session-conversation-area.tsx +308 -0
- package/src/features/chat/features/conversation/components/session-conversation-input.tsx +439 -0
- package/src/features/chat/features/conversation/hooks/use-session-conversation-controller.ts +194 -0
- package/src/features/chat/features/conversation/hooks/use-session-conversation-input-attachments.ts +66 -0
- package/src/features/chat/features/{input/hooks/use-chat-input-bar-query-state.ts → conversation/hooks/use-session-conversation-input-query.ts} +51 -20
- package/src/features/chat/features/conversation/hooks/use-session-conversation-input-state.ts +281 -0
- package/src/features/chat/features/conversation/utils/session-conversation-input-toolbar.utils.ts +158 -0
- package/src/features/chat/features/input/hooks/__tests__/use-chat-input-surface-state.test.tsx +56 -0
- package/src/features/chat/features/input/hooks/use-chat-input-surface-state.ts +117 -0
- package/src/features/chat/features/input/input-surface-plugins/__tests__/panel-app-reference-plugin.test.ts +77 -0
- package/src/features/chat/features/input/input-surface-plugins/__tests__/slash-command-plugin.test.ts +108 -0
- package/src/features/chat/features/input/input-surface-plugins/chat-input-product-plugin-adapters.types.ts +10 -0
- package/src/features/chat/features/input/input-surface-plugins/input-surface-search.utils.ts +108 -0
- package/src/features/chat/features/input/input-surface-plugins/panel-app-reference-plugin.utils.ts +108 -0
- package/src/features/chat/features/input/input-surface-plugins/slash-command-plugin.utils.ts +161 -0
- package/src/features/chat/features/input/utils/__tests__/chat-composer-state.utils.test.ts +22 -1
- package/src/features/chat/features/input/utils/__tests__/chat-inline-token.utils.test.ts +26 -13
- package/src/features/chat/features/input/utils/__tests__/ncp-chat-input-availability.utils.test.ts +7 -28
- package/src/features/chat/features/input/utils/chat-composer-state.utils.ts +6 -0
- package/src/features/chat/features/input/utils/chat-inline-token.utils.ts +26 -51
- package/src/features/chat/features/input/utils/chat-input-bar.utils.ts +2 -0
- package/src/features/chat/features/input/utils/ncp-chat-input-availability.utils.ts +5 -6
- package/src/features/chat/features/message/components/__tests__/chat-message-list.container.test.tsx +47 -12
- package/src/features/chat/features/message/components/chat-inline-panel-app-card.tsx +7 -7
- package/src/features/chat/features/message/components/chat-message-list.container.tsx +99 -18
- package/src/features/chat/features/message/utils/__tests__/chat-message.utils.test.ts +31 -12
- package/src/features/chat/features/message/utils/chat-message-markdown-part.utils.ts +38 -0
- package/src/features/chat/features/message/utils/chat-message-part.utils.ts +1 -1
- package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +7 -7
- package/src/features/chat/features/session/components/chat-sidebar-session-list.tsx +6 -6
- package/src/features/chat/features/session/components/session-context-icon.tsx +2 -2
- package/src/features/chat/features/session/components/session-header/__tests__/chat-session-project-badge.test.tsx +2 -2
- package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +1 -1
- package/src/features/chat/features/session/components/session-header/chat-session-header-menu-item.tsx +1 -1
- package/src/features/chat/features/session/components/session-header/chat-session-metadata-dialog.tsx +1 -1
- package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +3 -3
- package/src/features/chat/features/session/components/session-run-badge.tsx +1 -1
- package/src/features/chat/features/session/hooks/__tests__/use-chat-session-project.test.tsx +3 -30
- package/src/features/chat/features/session/hooks/use-chat-session-project.ts +0 -5
- package/src/features/chat/features/session/utils/chat-run-metadata.utils.ts +8 -0
- package/src/features/chat/features/session-type/components/__tests__/chat-session-type-menu.test.tsx +2 -2
- package/src/features/chat/features/session-type/components/__tests__/chat-session-type-option-item.test.tsx +2 -0
- package/src/features/chat/features/session-type/components/chat-session-type-menu.tsx +2 -2
- package/src/features/chat/features/session-type/components/chat-session-type-option-item.tsx +2 -2
- package/src/features/chat/features/session-type/hooks/use-chat-session-type-state.ts +10 -2
- package/src/features/chat/features/welcome/components/__tests__/chat-conversation-welcome.test.tsx +49 -31
- package/src/features/chat/features/welcome/components/__tests__/chat-welcome.test.tsx +2 -9
- package/src/features/chat/features/welcome/components/chat-conversation-welcome.tsx +21 -10
- package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +3 -3
- package/src/features/chat/features/welcome/components/chat-welcome-capability-grid.tsx +4 -4
- package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +14 -19
- package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +5 -5
- package/src/features/chat/features/welcome/components/chat-welcome.tsx +6 -6
- package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-project-options.utils.test.ts +6 -8
- package/src/features/chat/features/welcome/utils/chat-welcome-project-options.utils.ts +1 -16
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +54 -0
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +44 -76
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +5 -1
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel.tsx +7 -1
- package/src/features/chat/features/workspace/hooks/use-chat-conversation-workspace-state.ts +40 -31
- package/src/features/chat/features/workspace/utils/__tests__/chat-workspace-panel-view-model.utils.test.ts +59 -1
- package/src/features/chat/features/workspace/utils/chat-thread-workspace-session.utils.ts +109 -0
- package/src/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils.ts +44 -4
- package/src/features/chat/index.ts +0 -1
- package/src/features/chat/managers/__tests__/chat-session-list.manager.test.ts +51 -99
- package/src/features/chat/managers/__tests__/chat-thread.manager.test.ts +135 -21
- package/src/features/chat/managers/chat-session-list.manager.ts +12 -43
- package/src/features/chat/managers/chat-thread.manager.ts +108 -34
- package/src/features/chat/pages/__tests__/ncp-chat-page.test.ts +48 -1
- package/src/features/chat/pages/__tests__/ncp-chat-page.test.tsx +72 -0
- package/src/features/chat/pages/ncp-chat-page.tsx +0 -122
- package/src/features/chat/presenters/chat.presenter.ts +2 -19
- package/src/features/chat/stores/__tests__/chat-thread.store.test.ts +31 -0
- package/src/features/chat/stores/chat-thread.store.ts +42 -26
- package/src/features/panel-apps/components/panel-app-list-item.tsx +8 -8
- package/src/features/panel-apps/components/panel-app-toolbar.tsx +4 -4
- package/src/features/panel-apps/components/panel-apps-list.tsx +20 -20
- package/src/features/panel-apps/hooks/use-panel-apps.ts +2 -1
- package/src/features/pwa/managers/__tests__/pwa-shell-theme.manager.test.ts +70 -6
- package/src/features/pwa/managers/pwa-shell-theme.manager.ts +10 -5
- package/src/features/service-apps/components/service-action-authorization-dialog.tsx +8 -8
- package/src/features/service-apps/components/service-apps-panel.tsx +24 -24
- package/src/features/settings/components/config/provider-advanced-settings-section.tsx +5 -5
- package/src/features/settings/components/config/provider-auth-section.tsx +7 -7
- package/src/features/settings/components/config/provider-form.tsx +10 -10
- package/src/features/settings/components/config/provider-models-section.tsx +16 -16
- package/src/features/settings/components/config/provider-pill-selector.tsx +1 -1
- package/src/features/settings/pages/providers-config-page.tsx +17 -17
- package/src/platforms/desktop/components/__tests__/desktop-app-shell.test.tsx +50 -10
- package/src/platforms/desktop/components/desktop-app-shell.tsx +34 -10
- package/src/platforms/desktop/components/desktop-window-chrome.tsx +41 -16
- package/src/shared/components/config-split-page.tsx +11 -11
- package/src/shared/components/doc-browser/doc-browser-home-page.tsx +2 -2
- package/src/shared/components/doc-browser/doc-browser-panel-parts.tsx +4 -4
- package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +4 -4
- package/src/shared/components/doc-browser/doc-browser.tsx +3 -3
- package/src/shared/components/resizable-right-panel/resizable-right-panel.tsx +1 -1
- package/src/shared/components/ui/actions/icon-action-button.tsx +1 -1
- package/src/shared/components/ui/button.tsx +4 -4
- package/src/shared/components/ui/card.tsx +4 -4
- package/src/shared/components/ui/dialog.tsx +5 -5
- package/src/shared/components/ui/input.tsx +1 -1
- package/src/shared/components/ui/label.tsx +1 -1
- package/src/shared/components/ui/popover.tsx +1 -1
- package/src/shared/components/ui/select.tsx +3 -3
- package/src/shared/components/ui/switch.tsx +3 -3
- package/src/shared/components/ui/tab-strip/__tests__/compact-tab-strip.test.tsx +24 -1
- package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +8 -4
- package/src/shared/components/ui/tabs.tsx +4 -4
- package/src/shared/components/ui/textarea.tsx +1 -1
- package/src/shared/lib/i18n/locales/en-US/chat.json +20 -2
- package/src/shared/lib/i18n/locales/en-US/core.json +9 -2
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +20 -2
- package/src/shared/lib/i18n/locales/zh-CN/core.json +9 -2
- package/src/shared/lib/theme/index.ts +94 -52
- package/src/shared/lib/ui-document-title/__tests__/ui-document-title.test.ts +49 -0
- package/src/shared/lib/ui-document-title/index.ts +50 -21
- package/dist/assets/channels-list-page-D6jtziu4.js +0 -8
- package/dist/assets/chat-page-BBnNJoKG.js +0 -105
- package/dist/assets/config-split-page-BCJhqdK9.js +0 -1
- package/dist/assets/doc-browser-C8xOF_9F.js +0 -1
- package/dist/assets/doc-browser-DgQedeAn.js +0 -1
- package/dist/assets/doc-browser-context-B46tQGmO.js +0 -1
- package/dist/assets/index-7o1WdUbU.js +0 -103
- package/dist/assets/index-DQWmEWzk.css +0 -1
- package/dist/assets/mcp-marketplace-page-CWZN7ohK.js +0 -1
- package/dist/assets/mcp-marketplace-page-Dzull_4-.js +0 -40
- package/dist/assets/model-config-page-Cv0O3BIj.js +0 -1
- package/dist/assets/plus-Bnt56oqG.js +0 -1
- package/dist/assets/provider-scoped-model-input-Duuh7i3h.js +0 -1
- package/dist/assets/providers-config-page-CPDz0Lxc.js +0 -1
- package/dist/assets/remote-B0LMs8u7.js +0 -1
- package/dist/assets/rotate-cw-BfyG_KEF.js +0 -1
- package/dist/assets/runtime-config-page-q0fvv8ME.js +0 -1
- package/dist/assets/use-config-DZkBWIdL.js +0 -1
- package/dist/assets/x-CW2KO-Hz.js +0 -1
- package/src/features/chat/components/conversation/chat-conversation-alerts.tsx +0 -37
- package/src/features/chat/features/input/components/__tests__/chat-attachment-upload-limit.test.ts +0 -38
- package/src/features/chat/features/input/components/chat-input-bar.container.tsx +0 -496
- package/src/features/chat/features/message/utils/chat-message-inline-content.utils.ts +0 -95
- package/src/features/chat/managers/__tests__/chat-input.manager.test.ts +0 -448
- package/src/features/chat/managers/__tests__/chat-run-snapshot.manager.test.ts +0 -129
- package/src/features/chat/managers/__tests__/chat-run.manager.test.ts +0 -236
- package/src/features/chat/managers/__tests__/chat-session-preference-sync.manager.test.ts +0 -219
- package/src/features/chat/managers/chat-input.manager.ts +0 -430
- package/src/features/chat/managers/chat-run.manager.ts +0 -110
- package/src/features/chat/managers/chat-session-preference-sync.manager.ts +0 -142
- package/src/features/chat/stores/chat-input.store.ts +0 -104
- /package/dist/assets/{config-hints-CTqBnCDp.js → config-hints-BkYBc7z0.js} +0 -0
|
@@ -6,8 +6,9 @@ import { ChatSidebar } from "@/features/chat/components/layout/chat-sidebar";
|
|
|
6
6
|
import type { NcpSessionListItemView } from "@/features/chat/features/ncp/hooks/use-ncp-session-list-view";
|
|
7
7
|
import { useChatQueryStore } from "@/features/chat/stores/ncp-chat-query.store";
|
|
8
8
|
import { useChatSessionListStore } from "@/features/chat/stores/chat-session-list.store";
|
|
9
|
-
import { PREFERENCE_KEYS
|
|
10
|
-
|
|
9
|
+
import { PREFERENCE_KEYS } from "@/shared/lib/api";
|
|
10
|
+
import type { ChatSessionTypeOptionView } from "@/shared/lib/api";
|
|
11
|
+
import { viewportLayoutManager } from "@/app/managers/viewport-layout.manager";
|
|
11
12
|
const mocks = vi.hoisted(() => ({
|
|
12
13
|
createSession: vi.fn(() => "draft-session-key"),
|
|
13
14
|
goToSession: vi.fn(),
|
|
@@ -30,7 +31,6 @@ const mocks = vi.hoisted(() => ({
|
|
|
30
31
|
sessionItems: [] as NcpSessionListItemView[],
|
|
31
32
|
isLoading: false,
|
|
32
33
|
}));
|
|
33
|
-
|
|
34
34
|
vi.mock("@/shared/lib/api", async (importOriginal) => {
|
|
35
35
|
const actual = await importOriginal();
|
|
36
36
|
return {
|
|
@@ -39,14 +39,12 @@ vi.mock("@/shared/lib/api", async (importOriginal) => {
|
|
|
39
39
|
updatePreference: mocks.updatePreference,
|
|
40
40
|
};
|
|
41
41
|
});
|
|
42
|
-
|
|
43
42
|
function createSessionItem(
|
|
44
43
|
session: NcpSessionListItemView["session"],
|
|
45
44
|
runStatus?: NcpSessionListItemView["runStatus"],
|
|
46
45
|
): NcpSessionListItemView {
|
|
47
46
|
return { session, runStatus };
|
|
48
47
|
}
|
|
49
|
-
|
|
50
48
|
function setSessionTypes(
|
|
51
49
|
options: ChatSessionTypeOptionView[],
|
|
52
50
|
defaultType = "native",
|
|
@@ -63,7 +61,6 @@ function setSessionTypes(
|
|
|
63
61
|
},
|
|
64
62
|
});
|
|
65
63
|
}
|
|
66
|
-
|
|
67
64
|
function sidebarElement(variant?: "desktop" | "mobile") {
|
|
68
65
|
const queryClient = new QueryClient({
|
|
69
66
|
defaultOptions: {
|
|
@@ -79,14 +76,14 @@ function sidebarElement(variant?: "desktop" | "mobile") {
|
|
|
79
76
|
</QueryClientProvider>
|
|
80
77
|
);
|
|
81
78
|
}
|
|
82
|
-
|
|
83
79
|
function renderSidebar(variant?: "desktop" | "mobile") {
|
|
84
80
|
return render(sidebarElement(variant));
|
|
85
81
|
}
|
|
86
|
-
|
|
87
82
|
function expectCodexSelectedInSessionTypeMenu() {
|
|
88
83
|
fireEvent.click(screen.getByLabelText("Session Type"));
|
|
89
|
-
expect(
|
|
84
|
+
expect(
|
|
85
|
+
screen.getByRole("button", { name: /Codex/i }).getAttribute("aria-pressed"),
|
|
86
|
+
).toBe("true");
|
|
90
87
|
}
|
|
91
88
|
|
|
92
89
|
vi.mock("@/features/chat/components/providers/chat-presenter.provider", () => ({
|
|
@@ -191,6 +188,8 @@ vi.mock("@/features/system-status", () => ({
|
|
|
191
188
|
}));
|
|
192
189
|
|
|
193
190
|
function resetSidebarTestState() {
|
|
191
|
+
window.localStorage.clear();
|
|
192
|
+
viewportLayoutManager.resetForTests();
|
|
194
193
|
mocks.createSession.mockReset();
|
|
195
194
|
mocks.createSession.mockReturnValue("draft-session-key");
|
|
196
195
|
mocks.goToSession.mockReset();
|
|
@@ -208,10 +207,13 @@ function resetSidebarTestState() {
|
|
|
208
207
|
value: null,
|
|
209
208
|
});
|
|
210
209
|
mocks.updatePreference.mockReset();
|
|
211
|
-
mocks.updatePreference.mockImplementation(
|
|
212
|
-
key, value
|
|
213
|
-
|
|
214
|
-
|
|
210
|
+
mocks.updatePreference.mockImplementation(
|
|
211
|
+
async (key: string, value: string) => ({
|
|
212
|
+
key,
|
|
213
|
+
value,
|
|
214
|
+
updatedAt: "2026-06-17T00:00:00.000Z",
|
|
215
|
+
}),
|
|
216
|
+
);
|
|
215
217
|
mocks.updateNcpSession.mockReset();
|
|
216
218
|
mocks.updateNcpSession.mockResolvedValue({});
|
|
217
219
|
mocks.agents = [];
|
|
@@ -291,7 +293,7 @@ describe("ChatSidebar create and list basics", () => {
|
|
|
291
293
|
|
|
292
294
|
expect(
|
|
293
295
|
screen.getByTestId("brand-header").parentElement?.className,
|
|
294
|
-
).
|
|
296
|
+
).toMatch(/(?:^|\s)py-2(?:\s|$)/);
|
|
295
297
|
});
|
|
296
298
|
|
|
297
299
|
it("shows setup required status for runtime session types that are not ready yet", () => {
|
|
@@ -364,9 +366,9 @@ describe("ChatSidebar create and list basics", () => {
|
|
|
364
366
|
|
|
365
367
|
fireEvent.click(screen.getByRole("button", { name: "Settings menu" }));
|
|
366
368
|
fireEvent.click(screen.getByRole("combobox", { name: "Theme" }));
|
|
367
|
-
fireEvent.click(screen.getByRole("option", { name: "
|
|
369
|
+
fireEvent.click(screen.getByRole("option", { name: "Probe" }));
|
|
368
370
|
|
|
369
|
-
expect(mocks.setTheme).toHaveBeenCalledWith("
|
|
371
|
+
expect(mocks.setTheme).toHaveBeenCalledWith("probe");
|
|
370
372
|
});
|
|
371
373
|
|
|
372
374
|
it("creates the default session directly from the compact mobile add button when no menu is needed", () => {
|
|
@@ -50,7 +50,7 @@ export function ChatPageLayout({ view, confirmDialog }: ChatPageLayoutProps) {
|
|
|
50
50
|
{view === "chat" ? (
|
|
51
51
|
isMobile ? <ChatMobileShell /> : <ChatConversationPanel />
|
|
52
52
|
) : (
|
|
53
|
-
<section className="flex-1 min-h-0 overflow-hidden bg-
|
|
53
|
+
<section className="flex-1 min-h-0 overflow-hidden bg-background">
|
|
54
54
|
{view === "cron" ? (
|
|
55
55
|
<div className="h-full overflow-auto custom-scrollbar">
|
|
56
56
|
<div className="mx-auto w-full max-w-[min(1120px,100%)] px-4 py-4 sm:px-6 sm:py-5">
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { BrandHeader } from "@/shared/components/common/brand-header";
|
|
2
|
+
import { StatusBadge } from "@/shared/components/common/status-badge";
|
|
3
|
+
import { ChatSidebarListModeSwitch } from "@/features/chat/components/chat-sidebar-list-mode-switch";
|
|
4
|
+
import type {
|
|
5
|
+
groupSessionsByDate,
|
|
6
|
+
groupSessionsByProject,
|
|
7
|
+
} from "@/features/chat/features/session/utils/chat-sidebar-session-groups.utils";
|
|
8
|
+
import type { NcpSessionListItemView } from "@/features/chat/features/ncp/hooks/use-ncp-session-list-view";
|
|
9
|
+
import type { useSystemStatus } from "@/features/system-status";
|
|
10
|
+
import { cn } from "@/shared/lib/utils";
|
|
11
|
+
import { t, type I18nLanguage } from "@/shared/lib/i18n";
|
|
12
|
+
import type { UiTheme } from "@/shared/lib/theme";
|
|
13
|
+
import { SidebarNavLinkItem } from "@/app/components/layout/sidebar-items";
|
|
14
|
+
import { IconActionButton } from "@/shared/components/ui/actions/icon-action-button";
|
|
15
|
+
import {
|
|
16
|
+
AlarmClock,
|
|
17
|
+
Bot,
|
|
18
|
+
BrainCircuit,
|
|
19
|
+
PanelLeftClose,
|
|
20
|
+
PanelLeftOpen,
|
|
21
|
+
} from "lucide-react";
|
|
22
|
+
import { ChatSidebarSessionList } from "@/features/chat/features/session/components/chat-sidebar-session-list";
|
|
23
|
+
import { ChatSidebarUtilityMenu } from "@/features/chat/components/layout/chat-sidebar-utility-menu";
|
|
24
|
+
import { isWindowsDesktopHost } from "@/platforms/desktop";
|
|
25
|
+
import { viewportLayoutManager } from "@/app/managers/viewport-layout.manager";
|
|
26
|
+
import {
|
|
27
|
+
SIDEBAR_RAIL_CONTROL_CLASS,
|
|
28
|
+
SIDEBAR_RAIL_ICON_CLASS,
|
|
29
|
+
SIDEBAR_RAIL_PADDING_X_CLASS,
|
|
30
|
+
SIDEBAR_RAIL_STACK_CLASS,
|
|
31
|
+
SIDEBAR_RAIL_SURFACE_CLASS,
|
|
32
|
+
} from "@/app/components/layout/sidebar-rail.styles";
|
|
33
|
+
|
|
34
|
+
const navItems = [
|
|
35
|
+
{
|
|
36
|
+
target: "/cron",
|
|
37
|
+
label: () => t("chatSidebarScheduledTasks"),
|
|
38
|
+
icon: AlarmClock,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
target: "/skills",
|
|
42
|
+
label: () => t("chatSidebarSkills"),
|
|
43
|
+
icon: BrainCircuit,
|
|
44
|
+
},
|
|
45
|
+
{ target: "/agents", label: () => t("agentsPageTitle"), icon: Bot },
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
function ChatSidebarCollapseButton({ isCollapsed }: { isCollapsed: boolean }) {
|
|
49
|
+
const label = isCollapsed ? t("sidebarExpand") : t("sidebarCollapse");
|
|
50
|
+
const Icon = isCollapsed ? PanelLeftOpen : PanelLeftClose;
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<IconActionButton
|
|
54
|
+
icon={<Icon className={SIDEBAR_RAIL_ICON_CLASS} />}
|
|
55
|
+
label={label}
|
|
56
|
+
className={cn(SIDEBAR_RAIL_SURFACE_CLASS, isCollapsed && SIDEBAR_RAIL_CONTROL_CLASS)}
|
|
57
|
+
onClick={viewportLayoutManager.toggleSidebarCollapsed}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function ChatSidebarDesktopHeader({
|
|
63
|
+
connectionStatus,
|
|
64
|
+
isCollapsed,
|
|
65
|
+
}: {
|
|
66
|
+
connectionStatus: ReturnType<typeof useSystemStatus>["connectionStatus"];
|
|
67
|
+
isCollapsed: boolean;
|
|
68
|
+
}) {
|
|
69
|
+
const isWindowsHost = isWindowsDesktopHost();
|
|
70
|
+
const shouldReserveMacWindowControls =
|
|
71
|
+
typeof window !== "undefined" &&
|
|
72
|
+
window.nextclawDesktop?.platform === "darwin";
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<div
|
|
76
|
+
className={cn(
|
|
77
|
+
"flex items-center",
|
|
78
|
+
isCollapsed
|
|
79
|
+
? "justify-center px-2 py-1.5"
|
|
80
|
+
: isWindowsHost
|
|
81
|
+
? "justify-end px-3 py-1.5"
|
|
82
|
+
: "gap-2 px-5 py-2",
|
|
83
|
+
isCollapsed && shouldReserveMacWindowControls ? "pt-8" : null,
|
|
84
|
+
)}
|
|
85
|
+
>
|
|
86
|
+
{isCollapsed || isWindowsHost ? null : (
|
|
87
|
+
<BrandHeader
|
|
88
|
+
className="flex min-w-0 flex-1 items-center gap-2"
|
|
89
|
+
suffix={<StatusBadge status={connectionStatus} />}
|
|
90
|
+
/>
|
|
91
|
+
)}
|
|
92
|
+
<ChatSidebarCollapseButton isCollapsed={isCollapsed} />
|
|
93
|
+
</div>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function ChatSidebarDesktopNav({
|
|
98
|
+
isCollapsed,
|
|
99
|
+
}: {
|
|
100
|
+
isCollapsed: boolean;
|
|
101
|
+
}) {
|
|
102
|
+
return (
|
|
103
|
+
<>
|
|
104
|
+
<div className={cn("pb-2", isCollapsed ? "px-0" : "px-3")}>
|
|
105
|
+
<ul className={isCollapsed ? SIDEBAR_RAIL_STACK_CLASS : "space-y-0.5"}>
|
|
106
|
+
{navItems.map((item) => (
|
|
107
|
+
<li
|
|
108
|
+
key={item.target}
|
|
109
|
+
className={isCollapsed ? "flex justify-center" : undefined}
|
|
110
|
+
>
|
|
111
|
+
<SidebarNavLinkItem
|
|
112
|
+
to={item.target}
|
|
113
|
+
label={item.label()}
|
|
114
|
+
icon={item.icon}
|
|
115
|
+
density="compact"
|
|
116
|
+
collapsed={isCollapsed}
|
|
117
|
+
/>
|
|
118
|
+
</li>
|
|
119
|
+
))}
|
|
120
|
+
</ul>
|
|
121
|
+
</div>
|
|
122
|
+
<div
|
|
123
|
+
className={cn(
|
|
124
|
+
"border-t border-border/70",
|
|
125
|
+
isCollapsed ? "mx-2 my-1.5" : "mx-4",
|
|
126
|
+
)}
|
|
127
|
+
/>
|
|
128
|
+
</>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function ChatSidebarSessionArea({
|
|
133
|
+
defaultSessionType,
|
|
134
|
+
groups,
|
|
135
|
+
isCollapsed,
|
|
136
|
+
isLoading,
|
|
137
|
+
isProjectFirstView,
|
|
138
|
+
onCreateSession,
|
|
139
|
+
onSelectMode,
|
|
140
|
+
projectGroups,
|
|
141
|
+
renderSessionItem,
|
|
142
|
+
sessionTypeOptions,
|
|
143
|
+
}: {
|
|
144
|
+
defaultSessionType: string;
|
|
145
|
+
groups: ReturnType<typeof groupSessionsByDate>;
|
|
146
|
+
isCollapsed: boolean;
|
|
147
|
+
isLoading: boolean;
|
|
148
|
+
isProjectFirstView: boolean;
|
|
149
|
+
onCreateSession: (sessionType: string, projectRoot?: string | null) => void;
|
|
150
|
+
onSelectMode: (mode: "time-first" | "project-first") => void;
|
|
151
|
+
projectGroups: ReturnType<typeof groupSessionsByProject>;
|
|
152
|
+
renderSessionItem: (item: NcpSessionListItemView) => JSX.Element;
|
|
153
|
+
sessionTypeOptions: Parameters<
|
|
154
|
+
typeof ChatSidebarSessionList
|
|
155
|
+
>[0]["sessionTypeOptions"];
|
|
156
|
+
}) {
|
|
157
|
+
if (isCollapsed) {
|
|
158
|
+
return <div className="min-h-0 flex-1" aria-hidden="true" />;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<>
|
|
163
|
+
<div className="flex items-center justify-between px-5 pb-2 pt-3">
|
|
164
|
+
<div className="text-[11px] font-medium uppercase tracking-wider text-muted-foreground/75">
|
|
165
|
+
{t("chatSidebarTaskRecords")}
|
|
166
|
+
</div>
|
|
167
|
+
<ChatSidebarListModeSwitch
|
|
168
|
+
isProjectFirstView={isProjectFirstView}
|
|
169
|
+
onSelectMode={onSelectMode}
|
|
170
|
+
/>
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
<div className="flex-1 min-h-0 overflow-y-auto custom-scrollbar px-3 py-2">
|
|
174
|
+
<ChatSidebarSessionList
|
|
175
|
+
isLoading={isLoading}
|
|
176
|
+
isProjectFirstView={isProjectFirstView}
|
|
177
|
+
groups={groups}
|
|
178
|
+
projectGroups={projectGroups}
|
|
179
|
+
defaultSessionType={defaultSessionType}
|
|
180
|
+
sessionTypeOptions={sessionTypeOptions}
|
|
181
|
+
renderSessionItem={renderSessionItem}
|
|
182
|
+
onCreateSession={onCreateSession}
|
|
183
|
+
/>
|
|
184
|
+
</div>
|
|
185
|
+
</>
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function ChatSidebarDesktopFooter({
|
|
190
|
+
currentLanguage,
|
|
191
|
+
currentLanguageLabel,
|
|
192
|
+
currentTheme,
|
|
193
|
+
currentThemeLabel,
|
|
194
|
+
isCollapsed,
|
|
195
|
+
isOpen,
|
|
196
|
+
languageOptions,
|
|
197
|
+
onOpenApps,
|
|
198
|
+
onOpenChange,
|
|
199
|
+
onOpenDocs,
|
|
200
|
+
onSelectLanguage,
|
|
201
|
+
onSelectTheme,
|
|
202
|
+
themeOptions,
|
|
203
|
+
}: {
|
|
204
|
+
currentLanguage: I18nLanguage;
|
|
205
|
+
currentLanguageLabel: string;
|
|
206
|
+
currentTheme: UiTheme;
|
|
207
|
+
currentThemeLabel: string;
|
|
208
|
+
isCollapsed: boolean;
|
|
209
|
+
isOpen: boolean;
|
|
210
|
+
languageOptions: Array<{ value: I18nLanguage; label: string }>;
|
|
211
|
+
onOpenApps: () => void;
|
|
212
|
+
onOpenChange: (open: boolean) => void;
|
|
213
|
+
onOpenDocs: () => void;
|
|
214
|
+
onSelectLanguage: (language: I18nLanguage) => void;
|
|
215
|
+
onSelectTheme: (theme: UiTheme) => void;
|
|
216
|
+
themeOptions: Array<{
|
|
217
|
+
value: UiTheme;
|
|
218
|
+
label: string;
|
|
219
|
+
}>;
|
|
220
|
+
}) {
|
|
221
|
+
return (
|
|
222
|
+
<div
|
|
223
|
+
className={cn(
|
|
224
|
+
"border-t border-border/70 py-3",
|
|
225
|
+
isCollapsed
|
|
226
|
+
? cn("flex justify-center", SIDEBAR_RAIL_PADDING_X_CLASS)
|
|
227
|
+
: "px-3",
|
|
228
|
+
)}
|
|
229
|
+
>
|
|
230
|
+
<ChatSidebarUtilityMenu
|
|
231
|
+
isOpen={isOpen}
|
|
232
|
+
onOpenChange={onOpenChange}
|
|
233
|
+
currentTheme={currentTheme}
|
|
234
|
+
currentThemeLabel={currentThemeLabel}
|
|
235
|
+
themeOptions={themeOptions}
|
|
236
|
+
onSelectTheme={onSelectTheme}
|
|
237
|
+
currentLanguage={currentLanguage}
|
|
238
|
+
currentLanguageLabel={currentLanguageLabel}
|
|
239
|
+
languageOptions={languageOptions}
|
|
240
|
+
onSelectLanguage={onSelectLanguage}
|
|
241
|
+
onOpenDocs={onOpenDocs}
|
|
242
|
+
onOpenApps={onOpenApps}
|
|
243
|
+
collapsed={isCollapsed}
|
|
244
|
+
/>
|
|
245
|
+
</div>
|
|
246
|
+
);
|
|
247
|
+
}
|
|
@@ -8,12 +8,19 @@ import {
|
|
|
8
8
|
} from "@/shared/components/ui/popover";
|
|
9
9
|
import { SessionContextIconNode } from "@/features/chat/features/session/components/session-context-icon";
|
|
10
10
|
import { ChatSessionTypeMenu } from "@/features/chat/features/session-type/components/chat-session-type-menu";
|
|
11
|
-
import type {
|
|
11
|
+
import type { ChatSessionTypeOption } from "@/features/chat/features/session-type/utils/chat-session-type.utils";
|
|
12
12
|
import { cn } from "@/shared/lib/utils";
|
|
13
13
|
import { t } from "@/shared/lib/i18n";
|
|
14
14
|
import { Bot, ChevronDown, Plus, Search } from "lucide-react";
|
|
15
|
+
import {
|
|
16
|
+
SIDEBAR_RAIL_CONTROL_CLASS,
|
|
17
|
+
SIDEBAR_RAIL_ICON_CLASS,
|
|
18
|
+
SIDEBAR_RAIL_ITEM_GAP_CLASS,
|
|
19
|
+
SIDEBAR_RAIL_PRIMARY_SURFACE_CLASS,
|
|
20
|
+
SIDEBAR_RAIL_SURFACE_CLASS,
|
|
21
|
+
} from "@/app/components/layout/sidebar-rail.styles";
|
|
15
22
|
|
|
16
|
-
type SessionTypeOption =
|
|
23
|
+
type SessionTypeOption = ChatSessionTypeOption;
|
|
17
24
|
type NewSessionActionStyleVariant =
|
|
18
25
|
| "neutralSurface"
|
|
19
26
|
| "brandSoft"
|
|
@@ -34,23 +41,23 @@ const NEW_SESSION_ACTION_STYLE_CLASSES: Record<
|
|
|
34
41
|
neutralSurface: {
|
|
35
42
|
leftVariant: "ghost",
|
|
36
43
|
leftClassName:
|
|
37
|
-
"bg-
|
|
44
|
+
"bg-card text-foreground shadow-none transition-[background-color,color,box-shadow] hover:bg-accent hover:text-accent-foreground hover:shadow-sm active:bg-accent",
|
|
38
45
|
rightClassName:
|
|
39
|
-
"bg-
|
|
46
|
+
"bg-card text-muted-foreground shadow-none transition-[background-color,color,box-shadow] hover:bg-accent hover:text-accent-foreground hover:shadow-sm active:bg-accent",
|
|
40
47
|
},
|
|
41
48
|
brandSoft: {
|
|
42
49
|
leftVariant: "ghost",
|
|
43
50
|
leftClassName:
|
|
44
|
-
"bg-primary/10 text-primary shadow-none transition-[background-color,color,box-shadow] hover:bg-primary/15 hover:text-primary-700 hover:shadow-sm active:bg-primary/20",
|
|
51
|
+
"bg-primary/10 text-primary shadow-none ring-1 ring-primary/10 transition-[background-color,color,box-shadow] hover:bg-primary/15 hover:text-primary-700 hover:shadow-sm active:bg-primary/20",
|
|
45
52
|
rightClassName:
|
|
46
|
-
"bg-primary/10 text-primary shadow-none transition-[background-color,color,box-shadow] hover:bg-primary/15 hover:text-primary-700 hover:shadow-sm active:bg-primary/20",
|
|
53
|
+
"bg-primary/10 text-primary shadow-none ring-1 ring-primary/10 transition-[background-color,color,box-shadow] hover:bg-primary/15 hover:text-primary-700 hover:shadow-sm active:bg-primary/20",
|
|
47
54
|
},
|
|
48
55
|
brandTextSurface: {
|
|
49
56
|
leftVariant: "ghost",
|
|
50
57
|
leftClassName:
|
|
51
|
-
"bg-
|
|
58
|
+
"bg-card text-primary shadow-none transition-[background-color,color,box-shadow] hover:bg-accent hover:text-primary-700 hover:shadow-sm active:bg-primary/15",
|
|
52
59
|
rightClassName:
|
|
53
|
-
"bg-
|
|
60
|
+
"bg-card text-primary shadow-none transition-[background-color,color,box-shadow] hover:bg-accent hover:text-primary-700 hover:shadow-sm active:bg-primary/15",
|
|
54
61
|
},
|
|
55
62
|
brandSolid: {
|
|
56
63
|
leftVariant: "primary",
|
|
@@ -72,6 +79,7 @@ type ChatSidebarToolbarProps = {
|
|
|
72
79
|
onCreateSession: (sessionType: string) => void;
|
|
73
80
|
onSelectNewSessionType: (sessionType: string) => void;
|
|
74
81
|
onQueryChange: (query: string) => void;
|
|
82
|
+
collapsed?: boolean;
|
|
75
83
|
};
|
|
76
84
|
|
|
77
85
|
function getMobileCreateOptions(params: {
|
|
@@ -122,11 +130,73 @@ export function ChatSidebarDesktopToolbar(props: ChatSidebarToolbarProps) {
|
|
|
122
130
|
onCreateSession,
|
|
123
131
|
onSelectNewSessionType,
|
|
124
132
|
onQueryChange,
|
|
133
|
+
collapsed = false,
|
|
125
134
|
} = props;
|
|
126
135
|
const supportsSessionTypeSwitch = sessionTypeOptions.length > 1;
|
|
127
136
|
const actionStyle =
|
|
128
137
|
NEW_SESSION_ACTION_STYLE_CLASSES[NEW_SESSION_ACTION_STYLE_VARIANT];
|
|
129
138
|
|
|
139
|
+
if (collapsed) {
|
|
140
|
+
return (
|
|
141
|
+
<div className="px-2 pb-2">
|
|
142
|
+
<div
|
|
143
|
+
className={cn(
|
|
144
|
+
"flex flex-col items-center",
|
|
145
|
+
SIDEBAR_RAIL_ITEM_GAP_CLASS,
|
|
146
|
+
)}
|
|
147
|
+
>
|
|
148
|
+
<IconActionButton
|
|
149
|
+
icon={<Plus className={SIDEBAR_RAIL_ICON_CLASS} />}
|
|
150
|
+
label={t("chatSidebarNewTask")}
|
|
151
|
+
className={cn(
|
|
152
|
+
SIDEBAR_RAIL_CONTROL_CLASS,
|
|
153
|
+
SIDEBAR_RAIL_PRIMARY_SURFACE_CLASS,
|
|
154
|
+
)}
|
|
155
|
+
onClick={() => {
|
|
156
|
+
onCreateMenuOpenChange(false);
|
|
157
|
+
onCreateSession(selectedNewSessionType);
|
|
158
|
+
}}
|
|
159
|
+
/>
|
|
160
|
+
{supportsSessionTypeSwitch ? (
|
|
161
|
+
<Popover
|
|
162
|
+
open={isCreateMenuOpen}
|
|
163
|
+
onOpenChange={onCreateMenuOpenChange}
|
|
164
|
+
>
|
|
165
|
+
<PopoverTrigger asChild>
|
|
166
|
+
<IconActionButton
|
|
167
|
+
icon={
|
|
168
|
+
<SessionTypeTriggerIcon
|
|
169
|
+
option={selectedNewSessionTypeOption}
|
|
170
|
+
/>
|
|
171
|
+
}
|
|
172
|
+
label={t("chatSessionTypeLabel")}
|
|
173
|
+
className={cn(
|
|
174
|
+
SIDEBAR_RAIL_CONTROL_CLASS,
|
|
175
|
+
SIDEBAR_RAIL_SURFACE_CLASS,
|
|
176
|
+
)}
|
|
177
|
+
/>
|
|
178
|
+
</PopoverTrigger>
|
|
179
|
+
<PopoverContent
|
|
180
|
+
align="start"
|
|
181
|
+
side="right"
|
|
182
|
+
className="w-56 rounded-2xl border border-border bg-popover p-1.5 text-popover-foreground shadow-[0_24px_60px_-28px_rgba(15,23,42,0.38)]"
|
|
183
|
+
>
|
|
184
|
+
<ChatSessionTypeMenu
|
|
185
|
+
options={sessionTypeOptions}
|
|
186
|
+
selectedSessionType={selectedNewSessionType}
|
|
187
|
+
onSelect={(sessionType) => {
|
|
188
|
+
onSelectNewSessionType(sessionType);
|
|
189
|
+
onCreateMenuOpenChange(false);
|
|
190
|
+
}}
|
|
191
|
+
/>
|
|
192
|
+
</PopoverContent>
|
|
193
|
+
</Popover>
|
|
194
|
+
) : null}
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
130
200
|
return (
|
|
131
201
|
<>
|
|
132
202
|
<div className="px-4 pb-3">
|
|
@@ -136,9 +206,7 @@ export function ChatSidebarDesktopToolbar(props: ChatSidebarToolbarProps) {
|
|
|
136
206
|
className={cn(
|
|
137
207
|
"min-w-0 rounded-xl",
|
|
138
208
|
actionStyle.leftClassName,
|
|
139
|
-
supportsSessionTypeSwitch
|
|
140
|
-
? "flex-1 rounded-r-md"
|
|
141
|
-
: "w-full",
|
|
209
|
+
supportsSessionTypeSwitch ? "flex-1 rounded-r-md" : "w-full",
|
|
142
210
|
)}
|
|
143
211
|
onClick={() => {
|
|
144
212
|
onCreateMenuOpenChange(false);
|
|
@@ -157,7 +225,9 @@ export function ChatSidebarDesktopToolbar(props: ChatSidebarToolbarProps) {
|
|
|
157
225
|
<IconActionButton
|
|
158
226
|
icon={
|
|
159
227
|
<span className="inline-flex items-center gap-0.5">
|
|
160
|
-
<SessionTypeTriggerIcon
|
|
228
|
+
<SessionTypeTriggerIcon
|
|
229
|
+
option={selectedNewSessionTypeOption}
|
|
230
|
+
/>
|
|
161
231
|
<ChevronDown className="h-3 w-3 opacity-60" />
|
|
162
232
|
</span>
|
|
163
233
|
}
|
|
@@ -171,7 +241,7 @@ export function ChatSidebarDesktopToolbar(props: ChatSidebarToolbarProps) {
|
|
|
171
241
|
</PopoverTrigger>
|
|
172
242
|
<PopoverContent
|
|
173
243
|
align="end"
|
|
174
|
-
className="w-56 rounded-2xl border border-
|
|
244
|
+
className="w-56 rounded-2xl border border-border bg-popover p-1.5 text-popover-foreground shadow-[0_24px_60px_-28px_rgba(15,23,42,0.38)]"
|
|
175
245
|
>
|
|
176
246
|
<ChatSessionTypeMenu
|
|
177
247
|
options={sessionTypeOptions}
|
|
@@ -189,7 +259,7 @@ export function ChatSidebarDesktopToolbar(props: ChatSidebarToolbarProps) {
|
|
|
189
259
|
|
|
190
260
|
<div className="px-4 pb-3">
|
|
191
261
|
<div className="relative">
|
|
192
|
-
<Search className="absolute left-3 top-2.5 h-3.5 w-3.5 text-
|
|
262
|
+
<Search className="absolute left-3 top-2.5 h-3.5 w-3.5 text-muted-foreground/70" />
|
|
193
263
|
<Input
|
|
194
264
|
value={query}
|
|
195
265
|
onChange={(event) => onQueryChange(event.target.value)}
|
|
@@ -224,28 +294,31 @@ export function ChatSidebarMobileToolbar(props: ChatSidebarToolbarProps) {
|
|
|
224
294
|
<div className="px-4 pb-2 pt-1">
|
|
225
295
|
<div className="flex items-center gap-2">
|
|
226
296
|
<div className="relative min-w-0 flex-1">
|
|
227
|
-
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-
|
|
297
|
+
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground/70" />
|
|
228
298
|
<Input
|
|
229
299
|
value={query}
|
|
230
300
|
onChange={(event) => onQueryChange(event.target.value)}
|
|
231
301
|
placeholder={t("chatSidebarSearchPlaceholder")}
|
|
232
|
-
className="h-9 rounded-full border-transparent bg-
|
|
302
|
+
className="h-9 rounded-full border-transparent bg-muted pl-9 pr-3 text-[13px] shadow-none focus:border-border focus:bg-card"
|
|
233
303
|
/>
|
|
234
304
|
</div>
|
|
235
305
|
|
|
236
306
|
{hasCreateMenu ? (
|
|
237
|
-
<Popover
|
|
307
|
+
<Popover
|
|
308
|
+
open={isCreateMenuOpen}
|
|
309
|
+
onOpenChange={onCreateMenuOpenChange}
|
|
310
|
+
>
|
|
238
311
|
<PopoverTrigger asChild>
|
|
239
312
|
<IconActionButton
|
|
240
313
|
icon={<Plus className="h-4 w-4" />}
|
|
241
314
|
label={t("chatSidebarNewTask")}
|
|
242
315
|
tooltip={false}
|
|
243
|
-
className="h-9 w-9 shrink-0 rounded-full bg-
|
|
316
|
+
className="h-9 w-9 shrink-0 rounded-full bg-muted text-foreground shadow-none hover:bg-accent hover:text-accent-foreground"
|
|
244
317
|
/>
|
|
245
318
|
</PopoverTrigger>
|
|
246
319
|
<PopoverContent
|
|
247
320
|
align="end"
|
|
248
|
-
className="w-60 rounded-3xl border border-
|
|
321
|
+
className="w-60 rounded-3xl border border-border bg-popover p-2 text-popover-foreground shadow-[0_24px_70px_-30px_rgba(15,23,42,0.45)]"
|
|
249
322
|
>
|
|
250
323
|
<ChatSessionTypeMenu
|
|
251
324
|
options={createOptions}
|
|
@@ -263,7 +336,7 @@ export function ChatSidebarMobileToolbar(props: ChatSidebarToolbarProps) {
|
|
|
263
336
|
<IconActionButton
|
|
264
337
|
icon={<Plus className="h-4 w-4" />}
|
|
265
338
|
label={t("chatSidebarNewTask")}
|
|
266
|
-
className="h-9 w-9 shrink-0 rounded-full bg-
|
|
339
|
+
className="h-9 w-9 shrink-0 rounded-full bg-muted text-foreground shadow-none hover:bg-accent hover:text-accent-foreground"
|
|
267
340
|
onClick={() => onCreateSession(defaultSessionType)}
|
|
268
341
|
/>
|
|
269
342
|
)}
|