@chaaskit/client 0.1.0
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/dist/favicon.svg +11 -0
- package/dist/index.html +17 -0
- package/dist/lib/LoadingSkeletons-IcIC2JPq.js +132 -0
- package/dist/lib/LoadingSkeletons-IcIC2JPq.js.map +1 -0
- package/dist/lib/ServerThemeProvider-DNF0LAyk.js +42 -0
- package/dist/lib/ServerThemeProvider-DNF0LAyk.js.map +1 -0
- package/dist/lib/extensions.js +10 -0
- package/dist/lib/extensions.js.map +1 -0
- package/dist/lib/favicon.svg +11 -0
- package/dist/lib/index.js +74126 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/logo.svg +12 -0
- package/dist/lib/routes/AcceptInviteRoute.js +19 -0
- package/dist/lib/routes/AcceptInviteRoute.js.map +1 -0
- package/dist/lib/routes/AdminDashboardRoute.js +19 -0
- package/dist/lib/routes/AdminDashboardRoute.js.map +1 -0
- package/dist/lib/routes/AdminTeamRoute.js +19 -0
- package/dist/lib/routes/AdminTeamRoute.js.map +1 -0
- package/dist/lib/routes/AdminTeamsRoute.js +19 -0
- package/dist/lib/routes/AdminTeamsRoute.js.map +1 -0
- package/dist/lib/routes/AdminUsersRoute.js +19 -0
- package/dist/lib/routes/AdminUsersRoute.js.map +1 -0
- package/dist/lib/routes/ApiKeysRoute.js +19 -0
- package/dist/lib/routes/ApiKeysRoute.js.map +1 -0
- package/dist/lib/routes/AutomationsRoute.js +19 -0
- package/dist/lib/routes/AutomationsRoute.js.map +1 -0
- package/dist/lib/routes/ChatRoute.js +19 -0
- package/dist/lib/routes/ChatRoute.js.map +1 -0
- package/dist/lib/routes/DocumentsRoute.js +19 -0
- package/dist/lib/routes/DocumentsRoute.js.map +1 -0
- package/dist/lib/routes/OAuthConsentRoute.js +19 -0
- package/dist/lib/routes/OAuthConsentRoute.js.map +1 -0
- package/dist/lib/routes/PricingRoute.js +19 -0
- package/dist/lib/routes/PricingRoute.js.map +1 -0
- package/dist/lib/routes/PrivacyRoute.js +19 -0
- package/dist/lib/routes/PrivacyRoute.js.map +1 -0
- package/dist/lib/routes/TeamSettingsRoute.js +19 -0
- package/dist/lib/routes/TeamSettingsRoute.js.map +1 -0
- package/dist/lib/routes/TermsRoute.js +19 -0
- package/dist/lib/routes/TermsRoute.js.map +1 -0
- package/dist/lib/routes/VerifyEmailRoute.js +19 -0
- package/dist/lib/routes/VerifyEmailRoute.js.map +1 -0
- package/dist/lib/routes.js +79 -0
- package/dist/lib/routes.js.map +1 -0
- package/dist/lib/ssr-utils.js +29 -0
- package/dist/lib/ssr-utils.js.map +1 -0
- package/dist/lib/ssr.js +60 -0
- package/dist/lib/ssr.js.map +1 -0
- package/dist/lib/styles.css +2410 -0
- package/dist/lib/useExtensions-B5nX_8XD.js +155 -0
- package/dist/lib/useExtensions-B5nX_8XD.js.map +1 -0
- package/dist/logo.svg +12 -0
- package/package.json +84 -0
- package/src/components/AgentSelector.tsx +90 -0
- package/src/components/BranchModal.tsx +129 -0
- package/src/components/ClientOnly.tsx +27 -0
- package/src/components/ExportMenu.tsx +122 -0
- package/src/components/LoadingSkeletons.tsx +110 -0
- package/src/components/MCPCredentialsSection.tsx +309 -0
- package/src/components/MentionChip.tsx +149 -0
- package/src/components/MentionDropdown.tsx +175 -0
- package/src/components/MentionInput.tsx +293 -0
- package/src/components/MessageItem.tsx +300 -0
- package/src/components/MessageList.tsx +159 -0
- package/src/components/OAuthAppsSection.tsx +124 -0
- package/src/components/ProjectFolder.tsx +141 -0
- package/src/components/ProjectModal.tsx +296 -0
- package/src/components/SSRMessageList.tsx +153 -0
- package/src/components/SearchModal.tsx +173 -0
- package/src/components/SettingsModal.tsx +412 -0
- package/src/components/ShareModal.tsx +280 -0
- package/src/components/Sidebar.tsx +491 -0
- package/src/components/TeamSwitcher.tsx +273 -0
- package/src/components/ToolCallDisplay.tsx +473 -0
- package/src/components/ToolConfirmationModal.tsx +130 -0
- package/src/components/UsageChart.tsx +177 -0
- package/src/components/content/CodeBlock.tsx +69 -0
- package/src/components/content/MarkdownRenderer.tsx +64 -0
- package/src/components/content/SSRMarkdownRenderer.tsx +158 -0
- package/src/contexts/AuthContext.tsx +119 -0
- package/src/contexts/ConfigContext.tsx +214 -0
- package/src/contexts/ProjectContext.tsx +167 -0
- package/src/contexts/ServerConfigProvider.tsx +41 -0
- package/src/contexts/ServerThemeProvider.tsx +47 -0
- package/src/contexts/TeamContext.tsx +255 -0
- package/src/contexts/ThemeContext.tsx +113 -0
- package/src/extensions/index.ts +15 -0
- package/src/extensions/registry.ts +187 -0
- package/src/extensions/useExtensions.ts +52 -0
- package/src/hooks/useAppPath.ts +34 -0
- package/src/hooks/useBasePath.ts +13 -0
- package/src/hooks/useKeyboardShortcuts.ts +50 -0
- package/src/hooks/useMentionSearch.ts +106 -0
- package/src/index.tsx +116 -0
- package/src/layouts/MainLayout.tsx +98 -0
- package/src/pages/AcceptInvitePage.tsx +175 -0
- package/src/pages/AdminDashboardPage.tsx +362 -0
- package/src/pages/AdminTeamPage.tsx +304 -0
- package/src/pages/AdminTeamsPage.tsx +242 -0
- package/src/pages/AdminUsersPage.tsx +385 -0
- package/src/pages/ApiKeysPage.tsx +449 -0
- package/src/pages/ChatPage.tsx +310 -0
- package/src/pages/DocumentsPage.tsx +577 -0
- package/src/pages/LoginPage.tsx +232 -0
- package/src/pages/OAuthConsentPage.tsx +234 -0
- package/src/pages/PricingPage.tsx +314 -0
- package/src/pages/PrivacyPage.tsx +65 -0
- package/src/pages/RegisterPage.tsx +153 -0
- package/src/pages/ScheduledPromptsPage.tsx +702 -0
- package/src/pages/SharedThreadPage.tsx +116 -0
- package/src/pages/TeamSettingsPage.tsx +1085 -0
- package/src/pages/TermsPage.tsx +82 -0
- package/src/pages/VerifyEmailPage.tsx +202 -0
- package/src/routes/AcceptInviteRoute.tsx +24 -0
- package/src/routes/AdminDashboardRoute.tsx +24 -0
- package/src/routes/AdminTeamRoute.tsx +24 -0
- package/src/routes/AdminTeamsRoute.tsx +24 -0
- package/src/routes/AdminUsersRoute.tsx +24 -0
- package/src/routes/ApiKeysRoute.tsx +24 -0
- package/src/routes/AutomationsRoute.tsx +24 -0
- package/src/routes/ChatRoute.tsx +28 -0
- package/src/routes/DocumentsRoute.tsx +24 -0
- package/src/routes/OAuthConsentRoute.tsx +24 -0
- package/src/routes/PricingRoute.tsx +24 -0
- package/src/routes/PrivacyRoute.tsx +24 -0
- package/src/routes/TeamSettingsRoute.tsx +24 -0
- package/src/routes/TermsRoute.tsx +24 -0
- package/src/routes/VerifyEmailRoute.tsx +24 -0
- package/src/routes/index.ts +57 -0
- package/src/ssr-utils.tsx +84 -0
- package/src/ssr.ts +123 -0
- package/src/stores/chatStore.ts +670 -0
- package/src/styles/index.css +254 -0
- package/src/utils/api.ts +78 -0
- package/src/vite-env.d.ts +13 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { useState, useRef, useEffect } from 'react';
|
|
2
|
+
import { useTeam } from '../contexts/TeamContext';
|
|
3
|
+
import { useChatStore } from '../stores/chatStore';
|
|
4
|
+
|
|
5
|
+
export function TeamSwitcher() {
|
|
6
|
+
const { teams, currentTeamId, setCurrentTeamId, isLoadingTeams, createTeam } = useTeam();
|
|
7
|
+
const { loadThreads, clearCurrentThread } = useChatStore();
|
|
8
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
9
|
+
const [isCreating, setIsCreating] = useState(false);
|
|
10
|
+
const [newTeamName, setNewTeamName] = useState('');
|
|
11
|
+
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
12
|
+
|
|
13
|
+
const currentTeam = currentTeamId
|
|
14
|
+
? teams.find((t) => t.id === currentTeamId)
|
|
15
|
+
: null;
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
function handleClickOutside(event: MouseEvent) {
|
|
19
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
|
20
|
+
setIsOpen(false);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
25
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
26
|
+
}, []);
|
|
27
|
+
|
|
28
|
+
const handleSelect = async (teamId: string | null) => {
|
|
29
|
+
setCurrentTeamId(teamId);
|
|
30
|
+
setIsOpen(false);
|
|
31
|
+
clearCurrentThread();
|
|
32
|
+
// Reload threads for the new context
|
|
33
|
+
setTimeout(() => loadThreads(), 100);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const handleCreateTeam = async (e: React.FormEvent) => {
|
|
37
|
+
e.preventDefault();
|
|
38
|
+
if (!newTeamName.trim()) return;
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const team = await createTeam(newTeamName.trim());
|
|
42
|
+
setNewTeamName('');
|
|
43
|
+
setIsCreating(false);
|
|
44
|
+
handleSelect(team.id);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error('Failed to create team:', error);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
if (isLoadingTeams) {
|
|
51
|
+
return (
|
|
52
|
+
<div className="px-3 py-2 text-sm text-text-muted">
|
|
53
|
+
Loading teams...
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Show minimal version if user has no teams
|
|
59
|
+
if (teams.length === 0 && !isCreating) {
|
|
60
|
+
return (
|
|
61
|
+
<div className="relative" ref={dropdownRef}>
|
|
62
|
+
<button
|
|
63
|
+
onClick={() => setIsCreating(true)}
|
|
64
|
+
className="w-full flex items-center justify-center gap-2 px-3 py-2 text-sm rounded-md border border-dashed border-border text-text-muted hover:border-text-secondary hover:text-text-secondary transition-colors"
|
|
65
|
+
>
|
|
66
|
+
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
67
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
|
|
68
|
+
</svg>
|
|
69
|
+
Create a Team
|
|
70
|
+
</button>
|
|
71
|
+
|
|
72
|
+
{isCreating && (
|
|
73
|
+
<form
|
|
74
|
+
onSubmit={handleCreateTeam}
|
|
75
|
+
className="absolute z-50 w-full mt-1 p-3 rounded-md shadow-lg bg-background border border-border"
|
|
76
|
+
>
|
|
77
|
+
<input
|
|
78
|
+
type="text"
|
|
79
|
+
placeholder="Team name"
|
|
80
|
+
value={newTeamName}
|
|
81
|
+
onChange={(e) => setNewTeamName(e.target.value)}
|
|
82
|
+
autoFocus
|
|
83
|
+
className="w-full px-3 py-2 text-sm rounded border border-input-border bg-input-background text-text-primary focus:outline-none focus:border-primary"
|
|
84
|
+
/>
|
|
85
|
+
<div className="flex gap-2 mt-2">
|
|
86
|
+
<button
|
|
87
|
+
type="submit"
|
|
88
|
+
className="flex-1 px-3 py-1.5 text-sm rounded bg-primary text-white hover:opacity-90"
|
|
89
|
+
>
|
|
90
|
+
Create
|
|
91
|
+
</button>
|
|
92
|
+
<button
|
|
93
|
+
type="button"
|
|
94
|
+
onClick={() => {
|
|
95
|
+
setIsCreating(false);
|
|
96
|
+
setNewTeamName('');
|
|
97
|
+
}}
|
|
98
|
+
className="px-3 py-1.5 text-sm rounded border border-border text-text-secondary hover:bg-background-secondary"
|
|
99
|
+
>
|
|
100
|
+
Cancel
|
|
101
|
+
</button>
|
|
102
|
+
</div>
|
|
103
|
+
</form>
|
|
104
|
+
)}
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<div className="relative" ref={dropdownRef}>
|
|
111
|
+
<button
|
|
112
|
+
onClick={() => setIsOpen(!isOpen)}
|
|
113
|
+
className="w-full flex items-center justify-between px-3 py-2 text-sm rounded-md bg-background-secondary hover:bg-border transition-colors"
|
|
114
|
+
>
|
|
115
|
+
<div className="flex items-center gap-2 truncate">
|
|
116
|
+
<svg
|
|
117
|
+
className="w-4 h-4 flex-shrink-0"
|
|
118
|
+
fill="none"
|
|
119
|
+
stroke="currentColor"
|
|
120
|
+
viewBox="0 0 24 24"
|
|
121
|
+
>
|
|
122
|
+
{currentTeam ? (
|
|
123
|
+
<path
|
|
124
|
+
strokeLinecap="round"
|
|
125
|
+
strokeLinejoin="round"
|
|
126
|
+
strokeWidth={2}
|
|
127
|
+
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
|
|
128
|
+
/>
|
|
129
|
+
) : (
|
|
130
|
+
<path
|
|
131
|
+
strokeLinecap="round"
|
|
132
|
+
strokeLinejoin="round"
|
|
133
|
+
strokeWidth={2}
|
|
134
|
+
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
|
|
135
|
+
/>
|
|
136
|
+
)}
|
|
137
|
+
</svg>
|
|
138
|
+
<span className="truncate">
|
|
139
|
+
{currentTeam ? currentTeam.name : 'Personal'}
|
|
140
|
+
</span>
|
|
141
|
+
</div>
|
|
142
|
+
<svg
|
|
143
|
+
className={`w-4 h-4 flex-shrink-0 transition-transform ${isOpen ? 'rotate-180' : ''}`}
|
|
144
|
+
fill="none"
|
|
145
|
+
stroke="currentColor"
|
|
146
|
+
viewBox="0 0 24 24"
|
|
147
|
+
>
|
|
148
|
+
<path
|
|
149
|
+
strokeLinecap="round"
|
|
150
|
+
strokeLinejoin="round"
|
|
151
|
+
strokeWidth={2}
|
|
152
|
+
d="M19 9l-7 7-7-7"
|
|
153
|
+
/>
|
|
154
|
+
</svg>
|
|
155
|
+
</button>
|
|
156
|
+
|
|
157
|
+
{isOpen && (
|
|
158
|
+
<div className="absolute z-50 w-full mt-1 py-1 rounded-md shadow-lg bg-background border border-border">
|
|
159
|
+
<button
|
|
160
|
+
onClick={() => handleSelect(null)}
|
|
161
|
+
className={`w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-background-secondary ${
|
|
162
|
+
!currentTeamId ? 'text-primary' : 'text-text-primary'
|
|
163
|
+
}`}
|
|
164
|
+
>
|
|
165
|
+
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
166
|
+
<path
|
|
167
|
+
strokeLinecap="round"
|
|
168
|
+
strokeLinejoin="round"
|
|
169
|
+
strokeWidth={2}
|
|
170
|
+
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
|
|
171
|
+
/>
|
|
172
|
+
</svg>
|
|
173
|
+
Personal
|
|
174
|
+
{!currentTeamId && (
|
|
175
|
+
<svg className="w-4 h-4 ml-auto" fill="currentColor" viewBox="0 0 20 20">
|
|
176
|
+
<path
|
|
177
|
+
fillRule="evenodd"
|
|
178
|
+
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
|
179
|
+
clipRule="evenodd"
|
|
180
|
+
/>
|
|
181
|
+
</svg>
|
|
182
|
+
)}
|
|
183
|
+
</button>
|
|
184
|
+
|
|
185
|
+
{teams.length > 0 && (
|
|
186
|
+
<>
|
|
187
|
+
<div className="border-t border-border my-1" />
|
|
188
|
+
<div className="px-3 py-1 text-xs font-medium text-text-muted uppercase">
|
|
189
|
+
Teams
|
|
190
|
+
</div>
|
|
191
|
+
</>
|
|
192
|
+
)}
|
|
193
|
+
|
|
194
|
+
{teams.map((team) => (
|
|
195
|
+
<button
|
|
196
|
+
key={team.id}
|
|
197
|
+
onClick={() => handleSelect(team.id)}
|
|
198
|
+
className={`w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-background-secondary ${
|
|
199
|
+
currentTeamId === team.id ? 'text-primary' : 'text-text-primary'
|
|
200
|
+
}`}
|
|
201
|
+
>
|
|
202
|
+
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
203
|
+
<path
|
|
204
|
+
strokeLinecap="round"
|
|
205
|
+
strokeLinejoin="round"
|
|
206
|
+
strokeWidth={2}
|
|
207
|
+
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
|
|
208
|
+
/>
|
|
209
|
+
</svg>
|
|
210
|
+
<span className="truncate flex-1 text-left">{team.name}</span>
|
|
211
|
+
<span className="text-xs text-text-muted">
|
|
212
|
+
{team.memberCount}
|
|
213
|
+
</span>
|
|
214
|
+
{currentTeamId === team.id && (
|
|
215
|
+
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
|
|
216
|
+
<path
|
|
217
|
+
fillRule="evenodd"
|
|
218
|
+
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
|
219
|
+
clipRule="evenodd"
|
|
220
|
+
/>
|
|
221
|
+
</svg>
|
|
222
|
+
)}
|
|
223
|
+
</button>
|
|
224
|
+
))}
|
|
225
|
+
|
|
226
|
+
{/* Create Team */}
|
|
227
|
+
<div className="border-t border-border mt-1 pt-1">
|
|
228
|
+
{isCreating ? (
|
|
229
|
+
<form onSubmit={handleCreateTeam} className="p-2">
|
|
230
|
+
<input
|
|
231
|
+
type="text"
|
|
232
|
+
placeholder="Team name"
|
|
233
|
+
value={newTeamName}
|
|
234
|
+
onChange={(e) => setNewTeamName(e.target.value)}
|
|
235
|
+
autoFocus
|
|
236
|
+
className="w-full px-3 py-1.5 text-sm rounded border border-input-border bg-input-background text-text-primary focus:outline-none focus:border-primary"
|
|
237
|
+
/>
|
|
238
|
+
<div className="flex gap-2 mt-2">
|
|
239
|
+
<button
|
|
240
|
+
type="submit"
|
|
241
|
+
className="flex-1 px-3 py-1 text-xs rounded bg-primary text-white hover:opacity-90"
|
|
242
|
+
>
|
|
243
|
+
Create
|
|
244
|
+
</button>
|
|
245
|
+
<button
|
|
246
|
+
type="button"
|
|
247
|
+
onClick={() => {
|
|
248
|
+
setIsCreating(false);
|
|
249
|
+
setNewTeamName('');
|
|
250
|
+
}}
|
|
251
|
+
className="px-3 py-1 text-xs rounded border border-border text-text-secondary hover:bg-background-secondary"
|
|
252
|
+
>
|
|
253
|
+
Cancel
|
|
254
|
+
</button>
|
|
255
|
+
</div>
|
|
256
|
+
</form>
|
|
257
|
+
) : (
|
|
258
|
+
<button
|
|
259
|
+
onClick={() => setIsCreating(true)}
|
|
260
|
+
className="w-full flex items-center gap-2 px-3 py-2 text-sm text-text-muted hover:bg-background-secondary hover:text-text-primary"
|
|
261
|
+
>
|
|
262
|
+
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
263
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
|
|
264
|
+
</svg>
|
|
265
|
+
Create Team
|
|
266
|
+
</button>
|
|
267
|
+
)}
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
)}
|
|
271
|
+
</div>
|
|
272
|
+
);
|
|
273
|
+
}
|