@flowdrop/flowdrop 1.11.0 → 1.12.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/api/enhanced-client.d.ts +29 -16
- package/dist/api/enhanced-client.js +0 -14
- package/dist/components/PipelineStatus.svelte +9 -12
- package/dist/components/WorkflowEditor.svelte +3 -0
- package/dist/components/interrupt/ChoicePrompt.svelte +24 -5
- package/dist/components/interrupt/ConfirmationPrompt.svelte +5 -0
- package/dist/components/interrupt/InterruptBubble.svelte +12 -0
- package/dist/components/interrupt/ReviewPrompt.svelte +20 -0
- package/dist/components/interrupt/TextInputPrompt.svelte +5 -0
- package/dist/components/nodes/GatewayNode.svelte +2 -6
- package/dist/components/nodes/WorkflowNode.svelte +2 -6
- package/dist/components/playground/ChatInput.svelte +359 -0
- package/dist/components/playground/ChatInput.svelte.d.ts +14 -0
- package/dist/components/playground/ChatPanel.svelte +100 -724
- package/dist/components/playground/ChatPanel.svelte.d.ts +9 -26
- package/dist/components/playground/ControlPanel.svelte +496 -0
- package/dist/components/playground/ControlPanel.svelte.d.ts +20 -0
- package/dist/components/playground/ExecutionConsole.svelte +163 -0
- package/dist/components/playground/ExecutionConsole.svelte.d.ts +14 -0
- package/dist/components/playground/MessageStream.svelte +283 -0
- package/dist/components/playground/MessageStream.svelte.d.ts +27 -0
- package/dist/components/playground/PipelineKanbanView.svelte +284 -0
- package/dist/components/playground/PipelineKanbanView.svelte.d.ts +11 -0
- package/dist/components/playground/PipelinePanel.svelte +204 -65
- package/dist/components/playground/PipelinePanel.svelte.d.ts +3 -1
- package/dist/components/playground/PipelineTableView.svelte +376 -0
- package/dist/components/playground/PipelineTableView.svelte.d.ts +11 -0
- package/dist/components/playground/Playground.svelte +262 -1200
- package/dist/components/playground/Playground.svelte.d.ts +0 -13
- package/dist/components/playground/PlaygroundStudio.svelte +35 -61
- package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -1
- package/dist/components/playground/pipelineViewUtils.svelte.d.ts +22 -0
- package/dist/components/playground/pipelineViewUtils.svelte.js +77 -0
- package/dist/messages/defaults.d.ts +24 -0
- package/dist/messages/defaults.js +24 -0
- package/dist/playground/index.d.ts +6 -1
- package/dist/playground/index.js +6 -0
- package/dist/playground/mount.d.ts +3 -0
- package/dist/playground/mount.js +3 -2
- package/dist/stores/playgroundStore.svelte.d.ts +6 -0
- package/dist/stores/playgroundStore.svelte.js +21 -1
- package/dist/types/index.d.ts +28 -2
- package/dist/types/playground.d.ts +5 -2
- package/dist/types/playground.js +5 -7
- package/dist/utils/nodeStatus.js +15 -5
- package/package.json +1 -1
|
@@ -1,48 +1,31 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Component props
|
|
3
|
-
*/
|
|
4
1
|
interface Props {
|
|
5
|
-
/** Whether to show timestamps on messages */
|
|
6
2
|
showTimestamps?: boolean;
|
|
7
|
-
/** Whether to auto-scroll to bottom on new messages */
|
|
8
3
|
autoScroll?: boolean;
|
|
9
|
-
/** Placeholder text for the input */
|
|
10
4
|
placeholder?: string;
|
|
11
|
-
/** Callback when user sends a message */
|
|
12
5
|
onSendMessage?: (content: string) => void;
|
|
13
|
-
/** Callback when user requests to stop execution */
|
|
14
6
|
onStopExecution?: () => void;
|
|
15
|
-
/** Whether to show log messages inline (false = hide them) */
|
|
16
7
|
showLogsInline?: boolean;
|
|
17
|
-
/** Whether to enable markdown rendering in messages */
|
|
18
8
|
enableMarkdown?: boolean;
|
|
19
|
-
/** Callback when an interrupt is resolved (to refresh messages) */
|
|
20
9
|
onInterruptResolved?: () => void;
|
|
10
|
+
/** Render a "New session" CTA in the welcome state */
|
|
11
|
+
onCreateSession?: () => void;
|
|
21
12
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
13
|
+
* @deprecated Use `<MessageStream />` directly for view-only feeds.
|
|
14
|
+
* Kept for backwards compatibility with PlaygroundConfig URL params.
|
|
24
15
|
*/
|
|
25
16
|
showChatInput?: boolean;
|
|
26
17
|
/**
|
|
27
|
-
*
|
|
28
|
-
* When false, the Run button is hidden.
|
|
18
|
+
* @deprecated Use `<MessageStream />` directly for view-only feeds.
|
|
29
19
|
*/
|
|
30
20
|
showRunButton?: boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Predefined message to send when "Run" button is clicked
|
|
33
|
-
* Used when showChatInput is false.
|
|
34
|
-
*/
|
|
35
21
|
predefinedMessage?: string;
|
|
22
|
+
compactSystemMessages?: boolean;
|
|
36
23
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* instead of full chat bubbles to reduce visual noise.
|
|
40
|
-
* @default true
|
|
24
|
+
* @deprecated `showLogs` is now managed by playgroundStore.
|
|
25
|
+
* Setting it here syncs to the store on mount for backwards compatibility.
|
|
41
26
|
*/
|
|
42
|
-
compactSystemMessages?: boolean;
|
|
43
|
-
/** Whether log messages are visible — bindable so parent can host the toggle */
|
|
44
27
|
showLogs?: boolean;
|
|
45
28
|
}
|
|
46
|
-
declare const ChatPanel: import("svelte").Component<Props, {}, "
|
|
29
|
+
declare const ChatPanel: import("svelte").Component<Props, {}, "">;
|
|
47
30
|
type ChatPanel = ReturnType<typeof ChatPanel>;
|
|
48
31
|
export default ChatPanel;
|
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
ControlPanel Component
|
|
3
|
+
|
|
4
|
+
Where the user talks to the flow: session switcher, orchestration controls
|
|
5
|
+
(Run/Stop via ChatInput), and toolbar buttons (Pipeline toggle, Refresh,
|
|
6
|
+
Logs). Owns the session chip popover; delegates input behaviour to the
|
|
7
|
+
shared ChatInput primitive.
|
|
8
|
+
-->
|
|
9
|
+
|
|
10
|
+
<script lang="ts">
|
|
11
|
+
import Icon from '@iconify/svelte';
|
|
12
|
+
import ChatInput from './ChatInput.svelte';
|
|
13
|
+
import {
|
|
14
|
+
getCurrentSession,
|
|
15
|
+
getSessions,
|
|
16
|
+
getIsLoading,
|
|
17
|
+
getShowLogs,
|
|
18
|
+
playgroundActions
|
|
19
|
+
} from '../../stores/playgroundStore.svelte.js';
|
|
20
|
+
import { m } from '../../messages/index.js';
|
|
21
|
+
|
|
22
|
+
interface Props {
|
|
23
|
+
// Session management
|
|
24
|
+
onCreateSession: () => void;
|
|
25
|
+
onSelectSession: (id: string) => void;
|
|
26
|
+
onDeleteSession: (id: string) => void;
|
|
27
|
+
onSessionNavigate?: (id: string) => void;
|
|
28
|
+
// Orchestration
|
|
29
|
+
onSendMessage: (content: string) => void;
|
|
30
|
+
onStopExecution: () => void;
|
|
31
|
+
// Header actions
|
|
32
|
+
onTogglePanel?: () => void;
|
|
33
|
+
isPipelinePanelOpen?: boolean;
|
|
34
|
+
onRefresh: () => void;
|
|
35
|
+
isRefreshing?: boolean;
|
|
36
|
+
// Input config
|
|
37
|
+
showChatInput?: boolean;
|
|
38
|
+
showRunButton?: boolean;
|
|
39
|
+
predefinedMessage?: string;
|
|
40
|
+
placeholder?: string;
|
|
41
|
+
style?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let {
|
|
45
|
+
onCreateSession,
|
|
46
|
+
onSelectSession,
|
|
47
|
+
onDeleteSession,
|
|
48
|
+
onSessionNavigate,
|
|
49
|
+
onSendMessage,
|
|
50
|
+
onStopExecution,
|
|
51
|
+
onTogglePanel,
|
|
52
|
+
isPipelinePanelOpen = false,
|
|
53
|
+
onRefresh,
|
|
54
|
+
isRefreshing = false,
|
|
55
|
+
showChatInput = true,
|
|
56
|
+
showRunButton = true,
|
|
57
|
+
predefinedMessage,
|
|
58
|
+
placeholder,
|
|
59
|
+
style
|
|
60
|
+
}: Props = $props();
|
|
61
|
+
|
|
62
|
+
const cp = $derived(m().playground.controlPanel);
|
|
63
|
+
const logsTitle = $derived(getShowLogs() ? cp.hideLogs : cp.showLogs);
|
|
64
|
+
|
|
65
|
+
let sessionDropdownOpen = $state(false);
|
|
66
|
+
let chipWrapEl = $state<HTMLElement | null>(null);
|
|
67
|
+
let sessionChipEl = $state<HTMLElement | null>(null);
|
|
68
|
+
let sessionPopoverEl = $state<HTMLElement | null>(null);
|
|
69
|
+
|
|
70
|
+
$effect(() => {
|
|
71
|
+
if (sessionDropdownOpen && sessionPopoverEl) {
|
|
72
|
+
sessionPopoverEl.querySelector<HTMLElement>('[role="menuitem"]')?.focus();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Close popover on outside click
|
|
77
|
+
$effect(() => {
|
|
78
|
+
if (!sessionDropdownOpen) return;
|
|
79
|
+
function handleOutside(e: MouseEvent) {
|
|
80
|
+
if (!chipWrapEl?.contains(e.target as Node)) {
|
|
81
|
+
sessionDropdownOpen = false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
document.addEventListener('click', handleOutside);
|
|
85
|
+
return () => document.removeEventListener('click', handleOutside);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
function handleSelect(sessionId: string): void {
|
|
89
|
+
sessionDropdownOpen = false;
|
|
90
|
+
if (onSessionNavigate) {
|
|
91
|
+
onSessionNavigate(sessionId);
|
|
92
|
+
} else {
|
|
93
|
+
onSelectSession(sessionId);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function handleCreate(): void {
|
|
98
|
+
sessionDropdownOpen = false;
|
|
99
|
+
onCreateSession();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function handleDelete(event: Event, sessionId: string): void {
|
|
103
|
+
event.stopPropagation();
|
|
104
|
+
sessionDropdownOpen = false;
|
|
105
|
+
onDeleteSession(sessionId);
|
|
106
|
+
}
|
|
107
|
+
</script>
|
|
108
|
+
|
|
109
|
+
<section class="control-panel" {style}>
|
|
110
|
+
<header class="control-panel__header">
|
|
111
|
+
<Icon icon="mdi:message-text-outline" class="control-panel__icon" />
|
|
112
|
+
<span class="control-panel__label">{cp.sessionsLabel}</span>
|
|
113
|
+
|
|
114
|
+
<div class="control-panel__session-chip-wrap" bind:this={chipWrapEl}>
|
|
115
|
+
<button
|
|
116
|
+
type="button"
|
|
117
|
+
class="control-panel__session-chip"
|
|
118
|
+
class:control-panel__session-chip--open={sessionDropdownOpen}
|
|
119
|
+
bind:this={sessionChipEl}
|
|
120
|
+
aria-haspopup="menu"
|
|
121
|
+
aria-expanded={sessionDropdownOpen}
|
|
122
|
+
onclick={() => (sessionDropdownOpen = !sessionDropdownOpen)}
|
|
123
|
+
onkeydown={(e) => {
|
|
124
|
+
if (e.key === 'Escape') sessionDropdownOpen = false;
|
|
125
|
+
}}
|
|
126
|
+
title={cp.switchSession}
|
|
127
|
+
>
|
|
128
|
+
<span class="control-panel__session-chip-name">
|
|
129
|
+
{getCurrentSession()?.name ?? cp.noSession}
|
|
130
|
+
</span>
|
|
131
|
+
<Icon
|
|
132
|
+
icon={sessionDropdownOpen ? 'mdi:chevron-up' : 'mdi:chevron-down'}
|
|
133
|
+
class="control-panel__session-chip-chevron"
|
|
134
|
+
/>
|
|
135
|
+
</button>
|
|
136
|
+
|
|
137
|
+
{#if sessionDropdownOpen}
|
|
138
|
+
<div
|
|
139
|
+
class="control-panel__session-popover"
|
|
140
|
+
bind:this={sessionPopoverEl}
|
|
141
|
+
role="menu"
|
|
142
|
+
tabindex="-1"
|
|
143
|
+
onkeydown={(e) => {
|
|
144
|
+
if (e.key === 'Escape') {
|
|
145
|
+
sessionDropdownOpen = false;
|
|
146
|
+
sessionChipEl?.focus();
|
|
147
|
+
}
|
|
148
|
+
}}
|
|
149
|
+
>
|
|
150
|
+
<button
|
|
151
|
+
type="button"
|
|
152
|
+
role="menuitem"
|
|
153
|
+
class="control-panel__session-popover-item control-panel__session-popover-item--new"
|
|
154
|
+
disabled={getIsLoading()}
|
|
155
|
+
onclick={handleCreate}
|
|
156
|
+
>
|
|
157
|
+
<Icon icon="mdi:plus" />
|
|
158
|
+
<span>{cp.newSession}</span>
|
|
159
|
+
</button>
|
|
160
|
+
{#if getSessions().length > 0}
|
|
161
|
+
<div class="control-panel__session-popover-divider"></div>
|
|
162
|
+
{#each getSessions() as session (session.id)}
|
|
163
|
+
{@const isActive = getCurrentSession()?.id === session.id}
|
|
164
|
+
<div class="control-panel__session-popover-row">
|
|
165
|
+
<button
|
|
166
|
+
type="button"
|
|
167
|
+
role="menuitem"
|
|
168
|
+
class="control-panel__session-popover-item"
|
|
169
|
+
class:control-panel__session-popover-item--active={isActive}
|
|
170
|
+
onclick={() => handleSelect(session.id)}
|
|
171
|
+
>
|
|
172
|
+
{#if isActive}
|
|
173
|
+
<Icon icon="mdi:check" class="control-panel__session-popover-check" />
|
|
174
|
+
{:else}
|
|
175
|
+
<Icon icon="mdi:message-outline" />
|
|
176
|
+
{/if}
|
|
177
|
+
<span>{session.name}</span>
|
|
178
|
+
</button>
|
|
179
|
+
<button
|
|
180
|
+
type="button"
|
|
181
|
+
role="menuitem"
|
|
182
|
+
class="control-panel__session-popover-delete"
|
|
183
|
+
onclick={(e) => handleDelete(e, session.id)}
|
|
184
|
+
title={cp.deleteSession}
|
|
185
|
+
aria-label={cp.deleteSession}
|
|
186
|
+
>
|
|
187
|
+
<Icon icon="mdi:delete-outline" />
|
|
188
|
+
</button>
|
|
189
|
+
</div>
|
|
190
|
+
{/each}
|
|
191
|
+
{/if}
|
|
192
|
+
</div>
|
|
193
|
+
{/if}
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
<div class="control-panel__header-actions">
|
|
197
|
+
{#if onTogglePanel}
|
|
198
|
+
{@const pipelineTitle = isPipelinePanelOpen ? cp.hidePipeline : cp.showPipeline}
|
|
199
|
+
<button
|
|
200
|
+
type="button"
|
|
201
|
+
class="control-panel__toolbar-btn"
|
|
202
|
+
class:control-panel__toolbar-btn--active={isPipelinePanelOpen}
|
|
203
|
+
onclick={onTogglePanel}
|
|
204
|
+
title={pipelineTitle}
|
|
205
|
+
aria-label={pipelineTitle}
|
|
206
|
+
>
|
|
207
|
+
<Icon icon="mdi:source-branch" />
|
|
208
|
+
{cp.pipeline}
|
|
209
|
+
</button>
|
|
210
|
+
{/if}
|
|
211
|
+
{#if getCurrentSession()}
|
|
212
|
+
<button
|
|
213
|
+
type="button"
|
|
214
|
+
class="control-panel__toolbar-btn"
|
|
215
|
+
class:control-panel__toolbar-btn--spinning={isRefreshing}
|
|
216
|
+
onclick={onRefresh}
|
|
217
|
+
disabled={isRefreshing}
|
|
218
|
+
title={cp.refreshTitle}
|
|
219
|
+
aria-label={cp.refreshTitle}
|
|
220
|
+
>
|
|
221
|
+
<Icon icon="mdi:refresh" />
|
|
222
|
+
{cp.refresh}
|
|
223
|
+
</button>
|
|
224
|
+
{/if}
|
|
225
|
+
<button
|
|
226
|
+
type="button"
|
|
227
|
+
class="control-panel__toolbar-btn"
|
|
228
|
+
class:control-panel__toolbar-btn--active={getShowLogs()}
|
|
229
|
+
onclick={() => playgroundActions.toggleShowLogs()}
|
|
230
|
+
title={logsTitle}
|
|
231
|
+
aria-label={logsTitle}
|
|
232
|
+
>
|
|
233
|
+
<Icon icon="mdi:console" />
|
|
234
|
+
{cp.logs}
|
|
235
|
+
</button>
|
|
236
|
+
</div>
|
|
237
|
+
</header>
|
|
238
|
+
|
|
239
|
+
<ChatInput
|
|
240
|
+
showTextarea={showChatInput}
|
|
241
|
+
{showRunButton}
|
|
242
|
+
{placeholder}
|
|
243
|
+
{predefinedMessage}
|
|
244
|
+
{onSendMessage}
|
|
245
|
+
{onStopExecution}
|
|
246
|
+
/>
|
|
247
|
+
</section>
|
|
248
|
+
|
|
249
|
+
<style>
|
|
250
|
+
.control-panel {
|
|
251
|
+
display: flex;
|
|
252
|
+
flex-direction: column;
|
|
253
|
+
min-height: 0;
|
|
254
|
+
background-color: var(--fd-background);
|
|
255
|
+
border-top: 1px solid var(--fd-border);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.control-panel__header {
|
|
259
|
+
display: flex;
|
|
260
|
+
align-items: center;
|
|
261
|
+
gap: var(--fd-space-xs);
|
|
262
|
+
padding: 0 var(--fd-space-xl);
|
|
263
|
+
height: var(--fd-playground-header-height);
|
|
264
|
+
min-height: var(--fd-playground-header-height);
|
|
265
|
+
border-bottom: 1px solid var(--fd-border);
|
|
266
|
+
flex-shrink: 0;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
:global(.control-panel__icon) {
|
|
270
|
+
font-size: var(--fd-text-base);
|
|
271
|
+
color: var(--fd-muted-foreground);
|
|
272
|
+
flex-shrink: 0;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.control-panel__label {
|
|
276
|
+
font-size: var(--fd-text-sm);
|
|
277
|
+
font-weight: 600;
|
|
278
|
+
color: var(--fd-foreground);
|
|
279
|
+
flex-shrink: 0;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.control-panel__session-chip-wrap {
|
|
283
|
+
position: relative;
|
|
284
|
+
flex-shrink: 0;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.control-panel__session-chip {
|
|
288
|
+
display: inline-flex;
|
|
289
|
+
align-items: center;
|
|
290
|
+
gap: var(--fd-space-xs);
|
|
291
|
+
padding: var(--fd-space-3xs) var(--fd-space-sm) var(--fd-space-3xs) var(--fd-space-xs);
|
|
292
|
+
border: 1px solid var(--fd-border);
|
|
293
|
+
border-radius: var(--fd-radius-md);
|
|
294
|
+
background: var(--fd-background);
|
|
295
|
+
color: var(--fd-foreground);
|
|
296
|
+
font-size: var(--fd-text-sm);
|
|
297
|
+
font-weight: 500;
|
|
298
|
+
cursor: pointer;
|
|
299
|
+
transition: all var(--fd-transition-fast);
|
|
300
|
+
max-width: 220px;
|
|
301
|
+
line-height: 1;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.control-panel__session-chip :global(svg) {
|
|
305
|
+
flex-shrink: 0;
|
|
306
|
+
font-size: var(--fd-text-sm);
|
|
307
|
+
color: var(--fd-muted-foreground);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.control-panel__session-chip:hover,
|
|
311
|
+
.control-panel__session-chip--open {
|
|
312
|
+
background-color: var(--fd-muted);
|
|
313
|
+
border-color: var(--fd-border-strong);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.control-panel__session-chip-name {
|
|
317
|
+
flex: 1;
|
|
318
|
+
white-space: nowrap;
|
|
319
|
+
overflow: hidden;
|
|
320
|
+
text-overflow: ellipsis;
|
|
321
|
+
min-width: 0;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
:global(.control-panel__session-chip-chevron) {
|
|
325
|
+
color: var(--fd-muted-foreground);
|
|
326
|
+
flex-shrink: 0;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.control-panel__session-popover {
|
|
330
|
+
position: absolute;
|
|
331
|
+
bottom: calc(100% + var(--fd-space-xs));
|
|
332
|
+
left: 0;
|
|
333
|
+
z-index: 50;
|
|
334
|
+
min-width: 220px;
|
|
335
|
+
max-width: 300px;
|
|
336
|
+
padding: var(--fd-space-xs);
|
|
337
|
+
background-color: var(--fd-background);
|
|
338
|
+
border: 1px solid var(--fd-border);
|
|
339
|
+
border-radius: var(--fd-radius-lg);
|
|
340
|
+
box-shadow: var(--fd-shadow-lg);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.control-panel__session-popover-divider {
|
|
344
|
+
height: 1px;
|
|
345
|
+
background-color: var(--fd-border-muted);
|
|
346
|
+
margin: var(--fd-space-xs) 0;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.control-panel__session-popover-row {
|
|
350
|
+
display: flex;
|
|
351
|
+
align-items: center;
|
|
352
|
+
gap: 2px;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.control-panel__session-popover-item {
|
|
356
|
+
display: flex;
|
|
357
|
+
align-items: center;
|
|
358
|
+
gap: var(--fd-space-sm);
|
|
359
|
+
flex: 1;
|
|
360
|
+
min-width: 0;
|
|
361
|
+
padding: var(--fd-space-sm);
|
|
362
|
+
border: none;
|
|
363
|
+
border-radius: var(--fd-radius-sm);
|
|
364
|
+
background: transparent;
|
|
365
|
+
color: var(--fd-foreground);
|
|
366
|
+
font-size: var(--fd-text-sm);
|
|
367
|
+
text-align: left;
|
|
368
|
+
cursor: pointer;
|
|
369
|
+
transition: background-color var(--fd-transition-fast);
|
|
370
|
+
white-space: nowrap;
|
|
371
|
+
overflow: hidden;
|
|
372
|
+
text-overflow: ellipsis;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.control-panel__session-popover-item :global(svg) {
|
|
376
|
+
flex-shrink: 0;
|
|
377
|
+
color: var(--fd-muted-foreground);
|
|
378
|
+
font-size: var(--fd-text-sm);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.control-panel__session-popover-item span {
|
|
382
|
+
overflow: hidden;
|
|
383
|
+
text-overflow: ellipsis;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.control-panel__session-popover-item:hover {
|
|
387
|
+
background-color: var(--fd-muted);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.control-panel__session-popover-item:disabled {
|
|
391
|
+
opacity: 0.4;
|
|
392
|
+
cursor: not-allowed;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.control-panel__session-popover-item--new {
|
|
396
|
+
color: var(--fd-primary);
|
|
397
|
+
font-weight: 500;
|
|
398
|
+
width: 100%;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.control-panel__session-popover-item--new :global(svg) {
|
|
402
|
+
color: var(--fd-primary);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.control-panel__session-popover-item--active {
|
|
406
|
+
font-weight: 500;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
:global(.control-panel__session-popover-check) {
|
|
410
|
+
color: var(--fd-primary) !important;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.control-panel__session-popover-delete {
|
|
414
|
+
display: flex;
|
|
415
|
+
align-items: center;
|
|
416
|
+
justify-content: center;
|
|
417
|
+
flex-shrink: 0;
|
|
418
|
+
width: var(--fd-size-icon-btn);
|
|
419
|
+
height: var(--fd-size-icon-btn);
|
|
420
|
+
border: none;
|
|
421
|
+
border-radius: var(--fd-radius-sm);
|
|
422
|
+
background: transparent;
|
|
423
|
+
color: var(--fd-muted-foreground);
|
|
424
|
+
cursor: pointer;
|
|
425
|
+
opacity: 0;
|
|
426
|
+
transition: all var(--fd-transition-fast);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.control-panel__session-popover-row:hover .control-panel__session-popover-delete,
|
|
430
|
+
.control-panel__session-popover-row:focus-within .control-panel__session-popover-delete {
|
|
431
|
+
opacity: 1;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
.control-panel__session-popover-delete:hover {
|
|
435
|
+
background-color: var(--fd-error-muted);
|
|
436
|
+
color: var(--fd-error);
|
|
437
|
+
opacity: 1;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
.control-panel__header-actions {
|
|
441
|
+
display: flex;
|
|
442
|
+
align-items: center;
|
|
443
|
+
gap: var(--fd-space-xs);
|
|
444
|
+
margin-left: auto;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
.control-panel__toolbar-btn {
|
|
448
|
+
display: inline-flex;
|
|
449
|
+
align-items: center;
|
|
450
|
+
gap: var(--fd-space-3xs);
|
|
451
|
+
padding: var(--fd-space-3xs) var(--fd-space-sm);
|
|
452
|
+
border: 1px solid var(--fd-border);
|
|
453
|
+
border-radius: var(--fd-radius-md);
|
|
454
|
+
background: transparent;
|
|
455
|
+
color: var(--fd-muted-foreground);
|
|
456
|
+
font-size: var(--fd-text-xs);
|
|
457
|
+
font-weight: 500;
|
|
458
|
+
cursor: pointer;
|
|
459
|
+
transition: all var(--fd-transition-fast);
|
|
460
|
+
line-height: 1;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.control-panel__toolbar-btn :global(svg) {
|
|
464
|
+
font-size: var(--fd-text-xs);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.control-panel__toolbar-btn:hover:not(:disabled) {
|
|
468
|
+
background-color: var(--fd-muted);
|
|
469
|
+
color: var(--fd-foreground);
|
|
470
|
+
border-color: var(--fd-border-strong);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.control-panel__toolbar-btn:disabled {
|
|
474
|
+
opacity: 0.5;
|
|
475
|
+
cursor: not-allowed;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
.control-panel__toolbar-btn--active {
|
|
479
|
+
background-color: var(--fd-primary-muted);
|
|
480
|
+
border-color: var(--fd-primary);
|
|
481
|
+
color: var(--fd-primary);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
.control-panel__toolbar-btn--spinning :global(svg) {
|
|
485
|
+
animation: control-panel-spin 0.8s linear infinite;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
@keyframes control-panel-spin {
|
|
489
|
+
from {
|
|
490
|
+
transform: rotate(0deg);
|
|
491
|
+
}
|
|
492
|
+
to {
|
|
493
|
+
transform: rotate(360deg);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
onCreateSession: () => void;
|
|
3
|
+
onSelectSession: (id: string) => void;
|
|
4
|
+
onDeleteSession: (id: string) => void;
|
|
5
|
+
onSessionNavigate?: (id: string) => void;
|
|
6
|
+
onSendMessage: (content: string) => void;
|
|
7
|
+
onStopExecution: () => void;
|
|
8
|
+
onTogglePanel?: () => void;
|
|
9
|
+
isPipelinePanelOpen?: boolean;
|
|
10
|
+
onRefresh: () => void;
|
|
11
|
+
isRefreshing?: boolean;
|
|
12
|
+
showChatInput?: boolean;
|
|
13
|
+
showRunButton?: boolean;
|
|
14
|
+
predefinedMessage?: string;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
style?: string;
|
|
17
|
+
}
|
|
18
|
+
declare const ControlPanel: import("svelte").Component<Props, {}, "">;
|
|
19
|
+
type ControlPanel = ReturnType<typeof ControlPanel>;
|
|
20
|
+
export default ControlPanel;
|