@nextclaw/ui 0.3.14 → 0.3.16
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 +12 -0
- package/dist/assets/index-DuW0OWcM.js +298 -0
- package/dist/assets/index-xwCviEXg.css +1 -0
- package/dist/index.html +2 -2
- package/package.json +2 -1
- package/src/App.tsx +12 -21
- package/src/api/config.ts +3 -2
- package/src/components/config/ModelConfig.tsx +1 -1
- package/src/components/config/SessionsConfig.tsx +315 -175
- package/src/components/layout/Sidebar.tsx +22 -20
- package/src/components/ui/select.tsx +135 -0
- package/src/lib/i18n.ts +37 -0
- package/src/main.tsx +4 -1
- package/src/stores/ui.store.ts +0 -7
- package/dist/assets/index-DMFVPFFm.js +0 -255
- package/dist/assets/index-uqpsLADF.css +0 -1
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import * as SelectPrimitive from "@radix-ui/react-select"
|
|
3
|
+
import { Check, ChevronDown, ChevronUp } from "lucide-react"
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
|
|
6
|
+
const Select = SelectPrimitive.Root
|
|
7
|
+
const SelectGroup = SelectPrimitive.Group
|
|
8
|
+
const SelectValue = SelectPrimitive.Value
|
|
9
|
+
|
|
10
|
+
const SelectTrigger = React.forwardRef<
|
|
11
|
+
React.ElementRef<typeof SelectPrimitive.Trigger>,
|
|
12
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
|
|
13
|
+
>(({ className, children, ...props }, ref) => (
|
|
14
|
+
<SelectPrimitive.Trigger
|
|
15
|
+
ref={ref}
|
|
16
|
+
className={cn(
|
|
17
|
+
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-gray-200 bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 bg-white",
|
|
18
|
+
className
|
|
19
|
+
)}
|
|
20
|
+
{...props}
|
|
21
|
+
>
|
|
22
|
+
{children}
|
|
23
|
+
<SelectPrimitive.Icon asChild>
|
|
24
|
+
<ChevronDown className="h-4 w-4 opacity-50" />
|
|
25
|
+
</SelectPrimitive.Icon>
|
|
26
|
+
</SelectPrimitive.Trigger>
|
|
27
|
+
))
|
|
28
|
+
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
|
|
29
|
+
|
|
30
|
+
const SelectScrollUpButton = React.forwardRef<
|
|
31
|
+
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
|
|
32
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
|
|
33
|
+
>(({ className, ...props }, ref) => (
|
|
34
|
+
<SelectPrimitive.ScrollUpButton
|
|
35
|
+
ref={ref}
|
|
36
|
+
className={cn("flex cursor-default items-center justify-center py-1", className)}
|
|
37
|
+
{...props}
|
|
38
|
+
>
|
|
39
|
+
<ChevronUp className="h-4 w-4" />
|
|
40
|
+
</SelectPrimitive.ScrollUpButton>
|
|
41
|
+
))
|
|
42
|
+
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
|
|
43
|
+
|
|
44
|
+
const SelectScrollDownButton = React.forwardRef<
|
|
45
|
+
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
|
|
46
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
|
|
47
|
+
>(({ className, ...props }, ref) => (
|
|
48
|
+
<SelectPrimitive.ScrollDownButton
|
|
49
|
+
ref={ref}
|
|
50
|
+
className={cn("flex cursor-default items-center justify-center py-1", className)}
|
|
51
|
+
{...props}
|
|
52
|
+
>
|
|
53
|
+
<ChevronDown className="h-4 w-4" />
|
|
54
|
+
</SelectPrimitive.ScrollDownButton>
|
|
55
|
+
))
|
|
56
|
+
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName
|
|
57
|
+
|
|
58
|
+
const SelectContent = React.forwardRef<
|
|
59
|
+
React.ElementRef<typeof SelectPrimitive.Content>,
|
|
60
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
|
|
61
|
+
>(({ className, children, position = "popper", ...props }, ref) => (
|
|
62
|
+
<SelectPrimitive.Portal>
|
|
63
|
+
<SelectPrimitive.Content
|
|
64
|
+
ref={ref}
|
|
65
|
+
className={cn(
|
|
66
|
+
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 bg-white",
|
|
67
|
+
position === "popper" &&
|
|
68
|
+
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
69
|
+
className
|
|
70
|
+
)}
|
|
71
|
+
position={position}
|
|
72
|
+
{...props}
|
|
73
|
+
>
|
|
74
|
+
<SelectScrollUpButton />
|
|
75
|
+
<SelectPrimitive.Viewport
|
|
76
|
+
className={cn("p-1", position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]")}
|
|
77
|
+
>
|
|
78
|
+
{children}
|
|
79
|
+
</SelectPrimitive.Viewport>
|
|
80
|
+
<SelectScrollDownButton />
|
|
81
|
+
</SelectPrimitive.Content>
|
|
82
|
+
</SelectPrimitive.Portal>
|
|
83
|
+
))
|
|
84
|
+
SelectContent.displayName = SelectPrimitive.Content.displayName
|
|
85
|
+
|
|
86
|
+
const SelectLabel = React.forwardRef<
|
|
87
|
+
React.ElementRef<typeof SelectPrimitive.Label>,
|
|
88
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
|
|
89
|
+
>(({ className, ...props }, ref) => (
|
|
90
|
+
<SelectPrimitive.Label ref={ref} className={cn("px-2 py-1.5 text-sm font-semibold", className)} {...props} />
|
|
91
|
+
))
|
|
92
|
+
SelectLabel.displayName = SelectPrimitive.Label.displayName
|
|
93
|
+
|
|
94
|
+
const SelectItem = React.forwardRef<
|
|
95
|
+
React.ElementRef<typeof SelectPrimitive.Item>,
|
|
96
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
|
|
97
|
+
>(({ className, children, ...props }, ref) => (
|
|
98
|
+
<SelectPrimitive.Item
|
|
99
|
+
ref={ref}
|
|
100
|
+
className={cn(
|
|
101
|
+
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-gray-100 focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 hover:bg-gray-100",
|
|
102
|
+
className
|
|
103
|
+
)}
|
|
104
|
+
{...props}
|
|
105
|
+
>
|
|
106
|
+
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
107
|
+
<SelectPrimitive.ItemIndicator>
|
|
108
|
+
<Check className="h-4 w-4" />
|
|
109
|
+
</SelectPrimitive.ItemIndicator>
|
|
110
|
+
</span>
|
|
111
|
+
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
|
112
|
+
</SelectPrimitive.Item>
|
|
113
|
+
))
|
|
114
|
+
SelectItem.displayName = SelectPrimitive.Item.displayName
|
|
115
|
+
|
|
116
|
+
const SelectSeparator = React.forwardRef<
|
|
117
|
+
React.ElementRef<typeof SelectPrimitive.Separator>,
|
|
118
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
|
|
119
|
+
>(({ className, ...props }, ref) => (
|
|
120
|
+
<SelectPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
|
|
121
|
+
))
|
|
122
|
+
SelectSeparator.displayName = SelectPrimitive.Separator.displayName
|
|
123
|
+
|
|
124
|
+
export {
|
|
125
|
+
Select,
|
|
126
|
+
SelectGroup,
|
|
127
|
+
SelectValue,
|
|
128
|
+
SelectTrigger,
|
|
129
|
+
SelectContent,
|
|
130
|
+
SelectLabel,
|
|
131
|
+
SelectItem,
|
|
132
|
+
SelectSeparator,
|
|
133
|
+
SelectScrollUpButton,
|
|
134
|
+
SelectScrollDownButton,
|
|
135
|
+
}
|
package/src/lib/i18n.ts
CHANGED
|
@@ -100,6 +100,43 @@ export const LABELS: Record<string, { zh: string; en: string }> = {
|
|
|
100
100
|
replyDelayMs: { zh: '回复延迟(ms)', en: 'Reply Delay (ms)' },
|
|
101
101
|
secret: { zh: '密钥', en: 'Secret' },
|
|
102
102
|
|
|
103
|
+
// Sessions
|
|
104
|
+
sessionsPageTitle: { zh: '会话管理', en: 'Sessions' },
|
|
105
|
+
sessionsPageDescription: {
|
|
106
|
+
zh: '管理会话:筛选、按渠道分组、查看历史、改标签/偏好模型、清空和删除。',
|
|
107
|
+
en: 'Manage sessions: filter, group by channel, inspect history, edit metadata, clear, and delete.'
|
|
108
|
+
},
|
|
109
|
+
sessionsFiltersTitle: { zh: '筛选', en: 'Filters' },
|
|
110
|
+
sessionsFiltersDescription: { zh: '按关键词、活跃窗口和分组方式筛选会话。', en: 'Filter sessions by query, activity window, and grouping mode.' },
|
|
111
|
+
sessionsSearchPlaceholder: { zh: '搜索 key 或标签', en: 'Search session key or label' },
|
|
112
|
+
sessionsActiveMinutesPlaceholder: { zh: '活跃分钟(0=不限)', en: 'Active minutes (0 = no limit)' },
|
|
113
|
+
sessionsLimitPlaceholder: { zh: '展示上限', en: 'Limit' },
|
|
114
|
+
sessionsGroupModeLabel: { zh: '分组方式', en: 'Grouping' },
|
|
115
|
+
sessionsGroupModeAll: { zh: '不分组 / 全部', en: 'All (No grouping)' },
|
|
116
|
+
sessionsGroupModeByChannel: { zh: '按渠道分组', en: 'Group by channel' },
|
|
117
|
+
sessionsListTitle: { zh: '会话列表', en: 'Session list' },
|
|
118
|
+
sessionsTotalLabel: { zh: '总数', en: 'Total' },
|
|
119
|
+
sessionsCurrentLabel: { zh: '当前展示', en: 'Showing' },
|
|
120
|
+
sessionsLoading: { zh: '加载会话中...', en: 'Loading sessions...' },
|
|
121
|
+
sessionsEmpty: { zh: '暂无会话。', en: 'No sessions yet.' },
|
|
122
|
+
sessionsKeyLabel: { zh: '键', en: 'Key' },
|
|
123
|
+
sessionsChannelLabel: { zh: '渠道', en: 'Channel' },
|
|
124
|
+
sessionsMessagesLabel: { zh: '消息数', en: 'Messages' },
|
|
125
|
+
sessionsUpdatedLabel: { zh: '更新时间', en: 'Updated' },
|
|
126
|
+
sessionsLastRoleLabel: { zh: '最后角色', en: 'Last Role' },
|
|
127
|
+
sessionsLabelPlaceholder: { zh: '会话标签(可选)', en: 'Session label (optional)' },
|
|
128
|
+
sessionsModelPlaceholder: { zh: '偏好模型(可选)', en: 'Preferred model (optional)' },
|
|
129
|
+
sessionsShowHistory: { zh: '查看历史', en: 'View history' },
|
|
130
|
+
sessionsHideHistory: { zh: '隐藏历史', en: 'Hide history' },
|
|
131
|
+
sessionsSaveMeta: { zh: '保存元信息', en: 'Save metadata' },
|
|
132
|
+
sessionsClearHistory: { zh: '清空历史', en: 'Clear history' },
|
|
133
|
+
sessionsDeleteConfirm: { zh: '确认删除会话', en: 'Delete session' },
|
|
134
|
+
sessionsHistoryTitle: { zh: '历史', en: 'History' },
|
|
135
|
+
sessionsHistoryDescription: { zh: '最近 200 条消息(展示窗口)。', en: 'Latest 200 messages (display window).' },
|
|
136
|
+
sessionsHistoryLoading: { zh: '加载历史中...', en: 'Loading history...' },
|
|
137
|
+
sessionsApplyingChanges: { zh: '正在应用会话变更...', en: 'Applying session changes...' },
|
|
138
|
+
sessionsUnknownChannel: { zh: '未知渠道', en: 'Unknown channel' },
|
|
139
|
+
|
|
103
140
|
// UI
|
|
104
141
|
saveVerifyConnect: { zh: '保存并验证 / 连接', en: 'Save & Verify / Connect' },
|
|
105
142
|
|
package/src/main.tsx
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { StrictMode } from 'react';
|
|
2
2
|
import { createRoot } from 'react-dom/client';
|
|
3
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
3
4
|
import App from './App';
|
|
4
5
|
import './index.css';
|
|
5
6
|
|
|
6
7
|
createRoot(document.getElementById('root')!).render(
|
|
7
8
|
<StrictMode>
|
|
8
|
-
<
|
|
9
|
+
<BrowserRouter>
|
|
10
|
+
<App />
|
|
11
|
+
</BrowserRouter>
|
|
9
12
|
</StrictMode>
|
|
10
13
|
);
|
package/src/stores/ui.store.ts
CHANGED
|
@@ -3,10 +3,6 @@ import { create } from 'zustand';
|
|
|
3
3
|
type ConnectionStatus = 'connected' | 'disconnected' | 'connecting';
|
|
4
4
|
|
|
5
5
|
interface UiState {
|
|
6
|
-
// Active configuration tab
|
|
7
|
-
activeTab: 'model' | 'providers' | 'channels' | 'runtime' | 'sessions';
|
|
8
|
-
setActiveTab: (tab: UiState['activeTab']) => void;
|
|
9
|
-
|
|
10
6
|
// Connection status
|
|
11
7
|
connectionStatus: ConnectionStatus;
|
|
12
8
|
setConnectionStatus: (status: ConnectionStatus) => void;
|
|
@@ -23,9 +19,6 @@ interface UiState {
|
|
|
23
19
|
}
|
|
24
20
|
|
|
25
21
|
export const useUiStore = create<UiState>((set) => ({
|
|
26
|
-
activeTab: 'model',
|
|
27
|
-
setActiveTab: (tab) => set({ activeTab: tab }),
|
|
28
|
-
|
|
29
22
|
connectionStatus: 'disconnected',
|
|
30
23
|
setConnectionStatus: (status) => set({ connectionStatus: status }),
|
|
31
24
|
|