@iloveagents/foundry-web-ui 0.29.1 → 0.31.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/components/ag-ui-runtime-provider.d.ts +8 -3
- package/dist/components/ag-ui-runtime-provider.js +76 -33
- package/dist/components/assistant-chat.d.ts +1 -15
- package/dist/components/assistant-chat.js +4 -5
- package/dist/components/chat-bubble.js +3 -4
- package/dist/components/chat-context-items.d.ts +6 -0
- package/dist/components/chat-context-items.js +25 -0
- package/dist/components/chat-context.js +10 -2
- package/dist/components/chat-empty-state.js +1 -1
- package/dist/components/chat-header.js +2 -1
- package/dist/components/composer-add-menu.d.ts +0 -19
- package/dist/components/composer-add-menu.js +2 -10
- package/dist/components/context-badges.d.ts +0 -14
- package/dist/components/context-badges.js +2 -29
- package/dist/components/context-bar.d.ts +1 -21
- package/dist/components/context-bar.js +3 -74
- package/dist/components/focus-chat-pane.js +1 -1
- package/dist/components/markdown-text.js +6 -4
- package/dist/components/sidebar.js +51 -17
- package/dist/components/tool-panel.js +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.js +5 -4
- package/dist/lib/ag-ui-adapter.d.ts +3 -0
- package/dist/lib/ag-ui-adapter.js +75 -11
- package/dist/lib/auth-provider.js +1 -1
- package/dist/lib/chat-runs-store.d.ts +40 -0
- package/dist/lib/chat-runs-store.js +173 -0
- package/dist/lib/merge-chat-state.d.ts +3 -0
- package/dist/lib/merge-chat-state.js +21 -0
- package/dist/lib/nav-config.js +47 -20
- package/dist/lib/theme-runtime.d.ts +23 -0
- package/dist/lib/theme-runtime.js +210 -30
- package/dist/lib/theme-store.d.ts +3 -1
- package/dist/lib/theme-store.js +3 -2
- package/dist/lib/use-new-conversation.js +4 -8
- package/dist/styles.css +14 -0
- package/dist/workbench/chat-header.js +4 -3
- package/dist/workbench/conversation-history.d.ts +1 -1
- package/dist/workbench/conversation-history.js +75 -19
- package/dist/workbench/running-chats-menu.d.ts +3 -0
- package/dist/workbench/running-chats-menu.js +20 -0
- package/dist/workbench/selection-bridge.js +2 -5
- package/dist/workbench/use-workbench-state.d.ts +1 -2
- package/dist/workbench/use-workbench-state.js +15 -18
- package/dist/workbench/welcome-intro.js +1 -1
- package/dist/workbench/workbench-styles.js +54 -6
- package/dist/workbench/workbench.js +1 -1
- package/package.json +3 -3
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
export type ThemeMode = "light" | "dark" | "system";
|
|
8
8
|
interface ThemeState {
|
|
9
9
|
mode: ThemeMode;
|
|
10
|
-
setMode: (mode: ThemeMode
|
|
10
|
+
setMode: (mode: ThemeMode, options?: {
|
|
11
|
+
persist?: boolean;
|
|
12
|
+
}) => void;
|
|
11
13
|
/** Cycle through light -> dark -> system. */
|
|
12
14
|
cycle: () => void;
|
|
13
15
|
}
|
package/dist/lib/theme-store.js
CHANGED
|
@@ -38,8 +38,9 @@ export const useThemeStore = create((set, get) => {
|
|
|
38
38
|
}
|
|
39
39
|
return {
|
|
40
40
|
mode: initial,
|
|
41
|
-
setMode: (mode) => {
|
|
42
|
-
|
|
41
|
+
setMode: (mode, options) => {
|
|
42
|
+
if (options?.persist !== false)
|
|
43
|
+
localStorage.setItem(STORAGE_KEY, mode);
|
|
43
44
|
applyTheme(mode);
|
|
44
45
|
set({ mode });
|
|
45
46
|
},
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
2
|
import { useNavigate } from "react-router";
|
|
3
|
-
import { useAui } from "@assistant-ui/react";
|
|
4
|
-
import { useStore } from "zustand";
|
|
5
3
|
import { citationStore } from "@iloveagents/foundry-agent";
|
|
6
4
|
import { useAGUIAdapter } from "../components/ag-ui-runtime-provider.js";
|
|
7
5
|
import { useToolPanelStore } from "./tool-panel-store.js";
|
|
@@ -13,13 +11,11 @@ import { useChatLifecycleStore } from "./chat-lifecycle-store.js";
|
|
|
13
11
|
* Used by ChatHeader and Sidebar to keep behavior in sync.
|
|
14
12
|
*/
|
|
15
13
|
export function useNewConversation(options) {
|
|
16
|
-
const aui = useAui();
|
|
17
14
|
const { resetThread } = useAGUIAdapter();
|
|
18
15
|
const navigate = useNavigate();
|
|
19
16
|
const closePanel = useToolPanelStore((s) => s.closePanel);
|
|
20
17
|
const resetApp = useAppStore((s) => s.resetAll);
|
|
21
18
|
const closeMobile = useSidebarStore((s) => s.closeMobile);
|
|
22
|
-
const clearCitations = useStore(citationStore, (s) => s.clear);
|
|
23
19
|
return useCallback(() => {
|
|
24
20
|
const preserved = options?.preserveNavigation
|
|
25
21
|
? {
|
|
@@ -28,12 +24,15 @@ export function useNewConversation(options) {
|
|
|
28
24
|
}
|
|
29
25
|
: null;
|
|
30
26
|
closePanel();
|
|
27
|
+
const sentContext = useAppStore.getState().sentContext;
|
|
31
28
|
resetApp();
|
|
29
|
+
useAppStore.setState({ sentContext });
|
|
32
30
|
if (preserved) {
|
|
33
31
|
useAppStore.setState(preserved);
|
|
34
32
|
}
|
|
35
33
|
closeMobile();
|
|
36
|
-
|
|
34
|
+
// Clear only the foreground projection; retained transcripts keep their sources.
|
|
35
|
+
citationStore.setState({ threadId: null, results: [] });
|
|
37
36
|
// Notify the host app that a new thread is starting. Spaces wires
|
|
38
37
|
// this to clear its active-chat sticky id so the AGUIRuntimeProvider's
|
|
39
38
|
// ``effectiveThreadId`` advances to a freshly-minted UUID instead of
|
|
@@ -44,7 +43,6 @@ export function useNewConversation(options) {
|
|
|
44
43
|
// where there is no ``/`` navigation to clear sticky for us.
|
|
45
44
|
useChatLifecycleStore.getState().startNewConversation();
|
|
46
45
|
resetThread();
|
|
47
|
-
aui.threads().switchToNewThread();
|
|
48
46
|
if (options?.navigateToChat ?? true) {
|
|
49
47
|
navigate("/");
|
|
50
48
|
}
|
|
@@ -53,9 +51,7 @@ export function useNewConversation(options) {
|
|
|
53
51
|
resetApp,
|
|
54
52
|
options?.preserveNavigation,
|
|
55
53
|
closeMobile,
|
|
56
|
-
clearCitations,
|
|
57
54
|
resetThread,
|
|
58
|
-
aui,
|
|
59
55
|
options?.navigateToChat,
|
|
60
56
|
navigate,
|
|
61
57
|
]);
|
package/dist/styles.css
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
@theme inline {
|
|
2
|
+
--color-heading: var(--heading, var(--foreground));
|
|
3
|
+
--color-content-heading-1: var(--content-heading-1, var(--heading, var(--foreground)));
|
|
4
|
+
--color-content-heading-2: var(--content-heading-2, var(--heading, var(--foreground)));
|
|
5
|
+
--color-content-heading-3: var(--content-heading-3, var(--foreground));
|
|
6
|
+
--color-content-heading-4: var(--content-heading-4, var(--foreground));
|
|
7
|
+
--color-content-heading-5: var(--content-heading-5, var(--foreground));
|
|
8
|
+
--color-content-heading-6: var(--content-heading-6, var(--foreground));
|
|
2
9
|
--radius-xs: calc(var(--radius) - 6px);
|
|
3
10
|
--radius-sm: calc(var(--radius) - 4px);
|
|
4
11
|
--radius-md: calc(var(--radius) - 2px);
|
|
@@ -255,3 +262,10 @@ tr[data-state="selected"] > [data-pinned="cell"] {
|
|
|
255
262
|
tr[data-active] > [data-pinned="cell"] {
|
|
256
263
|
background-color: color-mix(in srgb, var(--primary) 8%, var(--pinned-surface));
|
|
257
264
|
}
|
|
265
|
+
|
|
266
|
+
@layer base {
|
|
267
|
+
:where(h1, h2, h3, h4, h5, h6) {
|
|
268
|
+
color: var(--heading, var(--foreground));
|
|
269
|
+
font-family: var(--font-heading, inherit);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { TooltipIconButton } from "../index.js";
|
|
3
|
-
import { SquarePen, PanelLeft, MessageSquare, Menu,
|
|
3
|
+
import { SquarePen, PanelLeft, MessageSquare, Menu, MessagesSquare, LoaderCircle, } from "lucide-react";
|
|
4
|
+
import { RunningChatsMenu } from "./running-chats-menu.js";
|
|
4
5
|
export function WorkbenchChatHeader({ collapsed, running, chatWidth, buttonClass, toggleNavigation, setCollapsed, showHistory, startChat, returnToChat, openHistory, chatOnly, setContentCollapsed, }) {
|
|
5
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { "data-chat-header": true, className: `relative flex shrink-0 items-center ${collapsed ? "justify-center" : "gap-1 px-2"}`, children: [!collapsed && !chatWidth.compact && (_jsx(TooltipIconButton, { tooltip: "Open navigation", className: `${buttonClass} preview-mobile-navigation`, "aria-label": "Open navigation", onClick: toggleNavigation, children: _jsx(Menu, { size: 18 }) })), collapsed ? (_jsx(TooltipIconButton, { tooltip: running ? "AI is working — expand chat" : "Expand chat", className: buttonClass, "aria-label": running ? "AI is working — expand chat" : "Expand chat", onClick: () => setCollapsed(false), children: running ? (_jsx(LoaderCircle, { size: 18, className: "animate-spin motion-reduce:animate-none text-primary" })) : (_jsx(MessageSquare, { size: 18 })) })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "min-w-0 flex-1 px-2 py-2", children: _jsx("div", { className: "text-sm font-semibold", children: showHistory ? "Conversations" : "Chat" }) }), _jsx(TooltipIconButton, { tooltip: "New chat", className: buttonClass, "aria-label": "New chat", onClick: startChat, children: _jsx(SquarePen, { size: 18 }) }), _jsx(TooltipIconButton, { tooltip: "Chat history", className: buttonClass, "aria-label": "Chat history", "aria-expanded": showHistory, onClick: () => (showHistory ? returnToChat() : openHistory()), children: _jsx(
|
|
6
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { "data-chat-header": true, className: `relative flex shrink-0 items-center ${collapsed ? "justify-center" : "gap-1 px-2"}`, children: [!collapsed && !chatWidth.compact && (_jsx(TooltipIconButton, { tooltip: "Open navigation", className: `${buttonClass} preview-mobile-navigation`, "aria-label": "Open navigation", onClick: toggleNavigation, children: _jsx(Menu, { size: 18 }) })), collapsed ? (_jsx(TooltipIconButton, { tooltip: running ? "AI is working — expand chat" : "Expand chat", className: buttonClass, "aria-label": running ? "AI is working — expand chat" : "Expand chat", onClick: () => setCollapsed(false), children: running ? (_jsx(LoaderCircle, { size: 18, className: "animate-spin motion-reduce:animate-none text-primary" })) : (_jsx(MessageSquare, { size: 18 })) })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "min-w-0 flex-1 px-2 py-2", children: _jsx("div", { className: "text-sm font-semibold", children: showHistory ? "Conversations" : "Chat" }) }), _jsx(RunningChatsMenu, { onOpen: returnToChat }), _jsx(TooltipIconButton, { tooltip: "New chat", className: buttonClass, "aria-label": "New chat", onClick: startChat, children: _jsx(SquarePen, { size: 18 }) }), _jsx(TooltipIconButton, { tooltip: "Chat history", className: buttonClass, "aria-label": "Chat history", "aria-expanded": showHistory, onClick: () => (showHistory ? returnToChat() : openHistory()), children: _jsx(MessagesSquare, { size: 18 }) }), _jsx(TooltipIconButton, { tooltip: "Collapse chat", style: chatOnly || chatWidth.compact ? { display: "none" } : undefined, className: buttonClass, "aria-label": "Collapse chat", onClick: () => {
|
|
6
7
|
setContentCollapsed(false);
|
|
7
8
|
setCollapsed(true);
|
|
8
9
|
}, children: _jsx(PanelLeft, { size: 18 }) })] }))] }), collapsed && (_jsxs("div", { "data-chat-rail": true, className: "flex flex-col items-center gap-1", children: [_jsx(TooltipIconButton, { tooltip: "Open navigation", className: `${buttonClass} preview-mobile-navigation`, "aria-label": "Open navigation", onClick: toggleNavigation, children: _jsx(Menu, { size: 18 }) }), _jsx(TooltipIconButton, { tooltip: "Chat history", className: buttonClass, "aria-label": "Chat history", onClick: () => {
|
|
9
10
|
setCollapsed(false);
|
|
10
11
|
openHistory();
|
|
11
|
-
}, children: _jsx(
|
|
12
|
+
}, children: _jsx(MessagesSquare, { size: 18 }) })] }))] }));
|
|
12
13
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { NavGroup } from "../
|
|
1
|
+
import type { NavGroup } from "../lib/nav-config.js";
|
|
2
2
|
/** History is a view of existing navigation targets, never a second chat runtime. */
|
|
3
3
|
export declare function ConversationHistory({ groups, workspaceId, onClose, showBack, welcome, compact, onViewAll, entityId, rootContext, }: {
|
|
4
4
|
groups: NavGroup[];
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, } from "../
|
|
2
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, } from "../ui/dropdown-menu.js";
|
|
3
3
|
import { Button, Input } from "@iloveagents/foundry-web-primitives";
|
|
4
4
|
import { Fragment, useEffect, useState } from "react";
|
|
5
5
|
import { Link } from "react-router";
|
|
6
|
-
import { ArrowLeft, MessageSquare, MoreHorizontal, Pin, Loader2, ChevronDown, Check,
|
|
6
|
+
import { ArrowLeft, MessageSquare, MoreHorizontal, Pin, Loader2, ChevronDown, Check, MessagesSquare, PauseCircle, Copy, } from "lucide-react";
|
|
7
|
+
import { useChatRuns, isChatRunActive } from "../lib/chat-runs-store.js";
|
|
7
8
|
/** History is a view of existing navigation targets, never a second chat runtime. */
|
|
8
9
|
export function ConversationHistory({ groups, workspaceId, onClose, showBack = true, welcome = false, compact = false, onViewAll, entityId, rootContext = false, }) {
|
|
9
10
|
const [loadingTo, setLoadingTo] = useState(null);
|
|
11
|
+
const [copiedId, setCopiedId] = useState(null);
|
|
10
12
|
const [loadError, setLoadError] = useState(null);
|
|
11
13
|
const [all, setAll] = useState(!workspaceId);
|
|
12
14
|
useEffect(() => setAll(!workspaceId), [workspaceId]);
|
|
@@ -16,28 +18,68 @@ export function ConversationHistory({ groups, workspaceId, onClose, showBack = t
|
|
|
16
18
|
groups
|
|
17
19
|
.filter((g) => g.meta?.type === "recent-chats" || g.meta?.type === "pinned-chats")
|
|
18
20
|
.flatMap((g) => g.items);
|
|
21
|
+
const runs = useChatRuns((s) => s.runs);
|
|
22
|
+
const runFor = (item) => Object.values(runs).find((run) => (run.conversationUrl ?? `/chat/${encodeURIComponent(run.threadId)}`) === item.to);
|
|
19
23
|
const workspaceItems = all || !workspaceId
|
|
20
24
|
? allItems
|
|
21
25
|
: (scoped?.meta?.workspaceConversations ?? scoped?.items ?? []);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
// In-memory runs appear immediately, before the server refreshes its nav rows.
|
|
27
|
+
// A persisted title/actions win, while the live run owns its current location.
|
|
28
|
+
const merged = new Map(workspaceItems.map((item) => [item.to, item]));
|
|
29
|
+
for (const run of Object.values(runs)) {
|
|
30
|
+
const to = run.conversationUrl ?? `/chat/${encodeURIComponent(run.threadId)}`;
|
|
31
|
+
const saved = allItems.find((item) => item.to === to);
|
|
32
|
+
if (saved && !isChatRunActive(run))
|
|
33
|
+
continue;
|
|
34
|
+
if (!all && workspaceId && !merged.has(to) && run.contextMeta?.spacesRootId !== workspaceId) {
|
|
35
|
+
merged.delete(to);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
merged.set(to, {
|
|
39
|
+
...saved,
|
|
40
|
+
to,
|
|
41
|
+
label: saved?.label ?? run.title,
|
|
42
|
+
icon: MessageSquare,
|
|
43
|
+
meta: {
|
|
44
|
+
...saved?.meta,
|
|
45
|
+
previewEntityId: run.contextMeta?.spacesEntityId ?? saved?.meta?.previewEntityId,
|
|
46
|
+
previewEntityName: run.pageLabel ?? saved?.meta?.previewEntityName,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const items = [...merged.values()]
|
|
51
|
+
.filter((item) => !(compact && workspaceId && !rootContext) ||
|
|
52
|
+
(Boolean(entityId) && item.meta?.previewEntityId === entityId))
|
|
53
|
+
.filter((item) => !["show-all-chats", "no-chats-placeholder"].includes(String(item.meta?.type)))
|
|
27
54
|
.filter((item) => item.label.toLocaleLowerCase().includes(search.toLocaleLowerCase()))
|
|
28
|
-
.sort((a, b) =>
|
|
55
|
+
.sort((a, b) => {
|
|
56
|
+
const active = (item) => {
|
|
57
|
+
const run = runFor(item);
|
|
58
|
+
return run && isChatRunActive(run) ? 1 : 0;
|
|
59
|
+
};
|
|
60
|
+
return (active(b) - active(a) || Number(Boolean(b.meta?.pinned)) - Number(Boolean(a.meta?.pinned)));
|
|
61
|
+
});
|
|
29
62
|
const visibleItems = compact ? items.slice(0, 3) : items;
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
63
|
+
const activeItems = visibleItems.filter((item) => {
|
|
64
|
+
const run = runFor(item);
|
|
65
|
+
return run && isChatRunActive(run);
|
|
66
|
+
});
|
|
67
|
+
const idleItems = visibleItems.filter((item) => !activeItems.includes(item));
|
|
68
|
+
const pinnedItems = idleItems.filter((item) => item.meta?.pinned);
|
|
69
|
+
const sections = compact
|
|
70
|
+
? [{ label: "", items: visibleItems }]
|
|
71
|
+
: [
|
|
72
|
+
{ label: "Running", items: activeItems },
|
|
33
73
|
{ label: "Pinned", items: pinnedItems },
|
|
34
|
-
{
|
|
35
|
-
|
|
36
|
-
|
|
74
|
+
{
|
|
75
|
+
label: activeItems.length || pinnedItems.length ? "Recent chats" : "",
|
|
76
|
+
items: idleItems.filter((item) => !item.meta?.pinned),
|
|
77
|
+
},
|
|
78
|
+
];
|
|
37
79
|
return (_jsxs("section", { "data-conversation-history": true, "aria-label": compact ? "Recent conversations" : "Chat history", className: compact ? "w-full" : "mx-auto flex min-h-0 w-full max-w-3xl flex-1 flex-col px-4 pb-4", children: [welcome && (_jsxs("div", { className: "pb-6 pt-8", children: [_jsx("h1", { className: "text-xl font-semibold", children: "How can I help?" }), _jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "Start something new or continue a recent chat." })] })), showBack && (_jsxs("button", { onClick: onClose, className: "mb-4 flex items-center gap-2 py-2 text-xs text-muted-foreground hover:text-foreground", children: [_jsx(ArrowLeft, { size: 14 }), " Back to chat"] })), (!compact || items.length > 0) && (_jsx("div", { className: "mb-2 mt-2 flex items-center justify-between", children: _jsx("h2", { className: compact ? "text-xs font-medium text-muted-foreground" : "text-base font-semibold", children: compact ? "Recent conversations" : "Conversation history" }) })), Boolean(workspaceId) && !compact && (_jsx("div", { className: "mb-3", children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", "aria-label": "History filter", className: "w-full justify-between font-normal shadow-none", children: [_jsx("span", { className: "truncate", children: all ? "All conversations" : "Last used in this workspace" }), _jsx(ChevronDown, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": "true" })] }) }), _jsx(DropdownMenuContent, { align: "start", className: "w-[var(--radix-dropdown-menu-trigger-width)]", children: [
|
|
38
80
|
{ value: false, label: "Last used in this workspace" },
|
|
39
81
|
{ value: true, label: "All conversations" },
|
|
40
|
-
].map((option) => (_jsxs(DropdownMenuItem, { role: "menuitemradio", "aria-checked": all === option.value, onSelect: () => setAll(option.value), children: [_jsx("span", { className: "flex-1", children: option.label }), all === option.value && _jsx(Check, { className: "size-4", "aria-hidden": "true" })] }, option.label))) })] }) })), !compact && (_jsx(Input, { "aria-label": "Search chats", placeholder: "Search chats", value: search, onChange: (event) => setSearch(event.target.value), className: "mb-3" })), loadError && (_jsx("p", { role: "alert", className: "mb-2 text-xs text-destructive", children: loadError })), _jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto", "aria-busy": Boolean(loadingTo), children: [sections
|
|
82
|
+
].map((option) => (_jsxs(DropdownMenuItem, { role: "menuitemradio", "aria-checked": all === option.value, onSelect: () => setAll(option.value), children: [_jsx("span", { className: "flex-1", children: option.label }), all === option.value && _jsx(Check, { className: "size-4", "aria-hidden": "true" })] }, option.label))) })] }) })), !compact && (_jsx(Input, { "aria-label": "Search chats", placeholder: "Search chats", value: search, onChange: (event) => setSearch(event.target.value), className: "mb-3" })), _jsx("span", { className: "sr-only", role: "status", children: copiedId ? "Chat ID copied" : "" }), loadError && (_jsx("p", { role: "alert", className: "mb-2 text-xs text-destructive", children: loadError })), _jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto", "aria-busy": Boolean(loadingTo), children: [sections
|
|
41
83
|
.filter((section) => section.items.length)
|
|
42
84
|
.map((section) => (_jsxs("section", { "aria-label": section.label || "Recent chats", className: "mb-4 last:mb-0", children: [section.label && (_jsx("h3", { "data-conversation-section-label": true, className: "px-2 py-2 text-xs font-medium text-muted-foreground", children: section.label })), section.items.map((item) => item.disabled ? (_jsx("p", { className: "py-3 text-sm text-muted-foreground", children: item.label }, item.to)) : (_jsxs("div", { className: "group flex items-center rounded-lg hover:bg-muted", children: [_jsxs(Link, { to: item.to, onClick: (event) => {
|
|
43
85
|
if (loadingTo) {
|
|
@@ -69,7 +111,7 @@ export function ConversationHistory({ groups, workspaceId, onClose, showBack = t
|
|
|
69
111
|
}
|
|
70
112
|
setLoadingTo(null);
|
|
71
113
|
onClose();
|
|
72
|
-
}, "data-conversation-row": true, className: "flex min-w-0 flex-1 items-center gap-2 rounded-lg px-2 py-1.5 text-sm hover:bg-muted focus-visible:outline-2 focus-visible:outline-primary", children: [loadingTo === item.to ? (_jsx(Loader2, { className: "size-4 shrink-0 animate-spin text-muted-foreground", "aria-label": "Opening chat" })) : item.meta?.pinned ? (_jsx(Pin, { className: "size-4 shrink-0 text-muted-foreground", "aria-label": "Pinned chat" })) : (_jsx(MessageSquare, { className: "size-4 shrink-0 text-muted-foreground" })), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate", children: item.label }), " ", (!compact || rootContext) && (_jsx("span", { className: "block truncate text-xs text-muted-foreground", children: !all &&
|
|
114
|
+
}, "data-conversation-row": true, className: "flex min-w-0 flex-1 items-center gap-2 rounded-lg px-2 py-1.5 text-sm hover:bg-muted focus-visible:outline-2 focus-visible:outline-primary", children: [loadingTo === item.to ? (_jsx(Loader2, { className: "size-4 shrink-0 animate-spin text-muted-foreground", "aria-label": "Opening chat" })) : runFor(item)?.status === "running" ? (_jsx(Loader2, { className: "size-4 shrink-0 animate-spin text-primary motion-reduce:animate-none", "aria-hidden": true })) : runFor(item)?.status === "waiting" ? (_jsx(PauseCircle, { className: "size-4 shrink-0 text-primary", "aria-hidden": true })) : item.meta?.pinned ? (_jsx(Pin, { className: "size-4 shrink-0 text-muted-foreground", "aria-label": "Pinned chat" })) : (_jsx(MessageSquare, { className: "size-4 shrink-0 text-muted-foreground" })), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate", children: item.label }), " ", runFor(item) && isChatRunActive(runFor(item)) ? (_jsx("span", { className: "block text-xs text-primary", children: runFor(item)?.status === "waiting" ? "Waiting for you" : "Running" })) : ((!compact || rootContext) && (_jsx("span", { className: "block truncate text-xs text-muted-foreground", children: !all &&
|
|
73
115
|
typeof item.meta?.previewEntityName === "string" &&
|
|
74
116
|
item.meta.previewEntityName
|
|
75
117
|
? `Last at ${item.meta.previewEntityName}`
|
|
@@ -80,7 +122,21 @@ export function ConversationHistory({ groups, workspaceId, onClose, showBack = t
|
|
|
80
122
|
? `Last in ${item.meta.previewSpaceName}`
|
|
81
123
|
: item.meta?.previewContextUnavailable
|
|
82
124
|
? "Location unavailable"
|
|
83
|
-
: "Last outside a workspace" }))] })] }),
|
|
84
|
-
|
|
85
|
-
|
|
125
|
+
: "Last outside a workspace" })))] })] }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": `Actions for ${item.label}`, className: "mr-1 inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 data-[state=open]:opacity-100 [@media(hover:none)]:opacity-100 hover:bg-background", children: _jsx(MoreHorizontal, { className: "size-4" }) }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsxs(DropdownMenuItem, { onSelect: () => {
|
|
126
|
+
const rawId = runFor(item)?.threadId ??
|
|
127
|
+
item.meta?.conversationId ??
|
|
128
|
+
item.to.split("/chat/")[1]?.split(/[?#]/)[0];
|
|
129
|
+
if (typeof rawId !== "string" || !rawId)
|
|
130
|
+
return;
|
|
131
|
+
const id = rawId;
|
|
132
|
+
void Promise.resolve()
|
|
133
|
+
.then(() => navigator.clipboard.writeText(decodeURIComponent(String(id))))
|
|
134
|
+
.then(() => {
|
|
135
|
+
setCopiedId(id);
|
|
136
|
+
setLoadError(null);
|
|
137
|
+
})
|
|
138
|
+
.catch(() => setLoadError(`Could not copy. Chat ID: ${decodeURIComponent(id)}`));
|
|
139
|
+
}, children: [_jsx(Copy, { className: "size-4" }), "Copy chat ID"] }), Boolean(item.actions?.length) && _jsx(DropdownMenuSeparator, {}), item.actions?.map((action) => (_jsxs(Fragment, { children: [action.separator && _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { onSelect: () => {
|
|
140
|
+
void action.handler();
|
|
141
|
+
}, className: action.destructive ? "text-destructive" : undefined, children: [_jsx(action.icon, { className: "mr-2 size-4" }), action.label] })] }, action.label)))] })] })] }, item.to)))] }, section.label))), items.length === 0 && !compact && (_jsx("p", { className: "py-3 text-sm text-muted-foreground", children: search ? "No matching chats" : "No chats yet" }))] }), compact && onViewAll && (_jsxs(Button, { variant: "ghost", size: "sm", onClick: onViewAll, className: "mt-1 h-9 w-fit gap-2 px-2 text-sm font-normal text-muted-foreground [@media(pointer:coarse)]:min-h-11", children: [_jsx(MessagesSquare, { className: "size-4", "aria-hidden": true }), "Conversation history"] }))] }));
|
|
86
142
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useAGUIAdapter } from "../components/ag-ui-runtime-provider.js";
|
|
3
|
+
import { useNavigate } from "react-router";
|
|
4
|
+
import { LoaderCircle, MessageSquare, PauseCircle } from "lucide-react";
|
|
5
|
+
import { useChatRuns, isChatRunActive } from "../lib/chat-runs-store.js";
|
|
6
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, } from "../ui/dropdown-menu.js";
|
|
7
|
+
export function RunningChatsMenu({ onOpen } = {}) {
|
|
8
|
+
const runs = useChatRuns((s) => s.runs);
|
|
9
|
+
const navigate = useNavigate();
|
|
10
|
+
const { selectRetainedThread } = useAGUIAdapter();
|
|
11
|
+
const active = Object.values(runs).filter(isChatRunActive);
|
|
12
|
+
if (!active.length)
|
|
13
|
+
return null;
|
|
14
|
+
return (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs("button", { type: "button", "aria-label": `${active.length} running conversations`, className: "inline-flex items-center gap-1.5 px-2 text-xs text-primary", children: [_jsx(LoaderCircle, { className: "size-3.5 animate-spin motion-reduce:animate-none" }), _jsx("span", { children: active.length })] }) }), _jsxs(DropdownMenuContent, { align: "end", className: "max-w-80", children: [_jsx(DropdownMenuLabel, { children: "Running in this browser" }), active.map((run) => (_jsxs(DropdownMenuItem, { onSelect: () => {
|
|
15
|
+
if (!selectRetainedThread(run.threadId)) {
|
|
16
|
+
navigate(run.conversationUrl ?? `/chat/${encodeURIComponent(run.threadId)}`);
|
|
17
|
+
}
|
|
18
|
+
onOpen?.();
|
|
19
|
+
}, children: [run.status === "waiting" ? (_jsx(PauseCircle, { className: "size-4 shrink-0" })) : (_jsx(MessageSquare, { className: "size-4 shrink-0" })), _jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "block truncate", children: run.title }), run.status === "waiting" && (_jsx("span", { className: "block text-xs text-muted-foreground", children: "Open to continue" }))] })] }, run.threadId)))] })] }));
|
|
20
|
+
}
|
|
@@ -60,12 +60,9 @@ export function SelectionBridge({ children }) {
|
|
|
60
60
|
.workbench-preview [data-sidebar-surface="desktop"] nav { padding-right: 16px; }
|
|
61
61
|
.workbench-preview [data-sidebar-surface="desktop"] { border-right-color: transparent; }
|
|
62
62
|
[data-connected-navigation="true"] [data-sidebar-surface="desktop"] [data-active-nav-row="true"] {
|
|
63
|
-
background: var(--background);
|
|
64
63
|
border-color: transparent; border-top-right-radius: 0; border-bottom-right-radius: 0;
|
|
65
64
|
}
|
|
66
|
-
` }), children, anchor && (
|
|
67
|
-
H ${anchor.rowRight} V ${anchor.top + anchor.height} H ${anchor.width - 8}
|
|
68
|
-
Q ${anchor.width},${anchor.top + anchor.height} ${anchor.width},${anchor.top + anchor.height + 7} Z` }), _jsx("path", { fill: "none", stroke: "var(--sidebar-ring)", strokeOpacity: 0.28, strokeWidth: 1, d: `M ${anchor.width + 12},0.5
|
|
65
|
+
` }), children, anchor && (_jsx("svg", { "aria-hidden": "true", className: "pointer-events-none absolute z-20", style: { inset: 0, width: anchor.width + anchor.surfaceWidth, height: anchor.navHeight }, viewBox: `0 0 ${anchor.width + anchor.surfaceWidth} ${anchor.navHeight}`, children: _jsx("path", { fill: "none", stroke: "var(--sidebar-ring)", strokeOpacity: 0.6, strokeWidth: 1, d: `M ${anchor.width + 12},0.5
|
|
69
66
|
H ${anchor.width + anchor.surfaceWidth - 12}
|
|
70
67
|
Q ${anchor.width + anchor.surfaceWidth - 0.5},0.5 ${anchor.width + anchor.surfaceWidth - 0.5},12
|
|
71
68
|
V ${anchor.navHeight - 12}
|
|
@@ -80,5 +77,5 @@ export function SelectionBridge({ children }) {
|
|
|
80
77
|
Q ${anchor.left},${anchor.top + 0.5} ${anchor.left + 12},${anchor.top + 0.5}
|
|
81
78
|
H ${anchor.width - 8}
|
|
82
79
|
Q ${anchor.width - 0.5},${anchor.top + 0.5} ${anchor.width - 0.5},${anchor.top - 7}
|
|
83
|
-
V 12 Q ${anchor.width - 0.5},0.5 ${anchor.width + 12},0.5 Z` })
|
|
80
|
+
V 12 Q ${anchor.width - 0.5},0.5 ${anchor.width + 12},0.5 Z` }) }))] }));
|
|
84
81
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { NavItem } from "../lib/nav-config.js";
|
|
2
1
|
export declare function normalizeWorkbenchPath(path: string): string;
|
|
3
2
|
export declare function useWorkbenchState(chatRoute: boolean): {
|
|
4
3
|
panelOpen: boolean;
|
|
@@ -38,7 +37,7 @@ export declare function useWorkbenchState(chatRoute: boolean): {
|
|
|
38
37
|
label: string;
|
|
39
38
|
tree?: boolean;
|
|
40
39
|
icon?: import("lucide-react").LucideIcon;
|
|
41
|
-
items: NavItem[];
|
|
40
|
+
items: import("../index.js").NavItem[];
|
|
42
41
|
priority?: number;
|
|
43
42
|
defaultCollapsed?: boolean;
|
|
44
43
|
to?: string;
|
|
@@ -4,22 +4,12 @@ import { useAuiState } from "@assistant-ui/react";
|
|
|
4
4
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { Button } from "@iloveagents/foundry-web-primitives";
|
|
6
6
|
import { useSidebarStore, useChatBubbleStore, useToolPanelStore, useNewConversation, useNavStore, useAppStore, } from "../index.js";
|
|
7
|
-
import {
|
|
7
|
+
import { MessagesSquare, Settings, Layers } from "lucide-react";
|
|
8
8
|
import { useChatWidth } from "./use-chat-width.js";
|
|
9
|
+
import { findNavItem } from "../lib/nav-config.js";
|
|
9
10
|
export function normalizeWorkbenchPath(path) {
|
|
10
11
|
return path === "/" ? path : path.replace(/\/+$/, "");
|
|
11
12
|
}
|
|
12
|
-
function findExactWorkbenchItem(items, pathname) {
|
|
13
|
-
const target = normalizeWorkbenchPath(pathname);
|
|
14
|
-
for (const item of items) {
|
|
15
|
-
if (normalizeWorkbenchPath(item.to) === target)
|
|
16
|
-
return item;
|
|
17
|
-
const nested = item.children && findExactWorkbenchItem(item.children, pathname);
|
|
18
|
-
if (nested)
|
|
19
|
-
return nested;
|
|
20
|
-
}
|
|
21
|
-
return undefined;
|
|
22
|
-
}
|
|
23
13
|
function useWorkbenchNavigation() {
|
|
24
14
|
const navGroups = useNavStore((s) => s.config);
|
|
25
15
|
const workspaceGroups = useMemo(() => {
|
|
@@ -33,9 +23,12 @@ function useWorkbenchNavigation() {
|
|
|
33
23
|
const space = workspaceGroups[0];
|
|
34
24
|
const root = space.items.find((item) => item.to === space.focusOn) ?? space.items[0];
|
|
35
25
|
return [
|
|
26
|
+
...navGroups
|
|
27
|
+
.filter((group) => group.meta?.showInWorkspaceNavigation)
|
|
28
|
+
.map((group) => ({ ...group, priority: 1100 })),
|
|
36
29
|
{
|
|
37
30
|
...space,
|
|
38
|
-
label: "
|
|
31
|
+
label: "All spaces",
|
|
39
32
|
icon: Layers,
|
|
40
33
|
priority: 1000,
|
|
41
34
|
items: root
|
|
@@ -56,7 +49,7 @@ function useWorkbenchNavigation() {
|
|
|
56
49
|
...navGroups
|
|
57
50
|
.filter((group) => !["recent-chats", "pinned-chats"].includes(String(group.meta?.type)))
|
|
58
51
|
.map((group) => group.meta?.type === "spaces-workspaces"
|
|
59
|
-
? { ...group, label: "
|
|
52
|
+
? { ...group, label: "All spaces", icon: Layers, createActions: undefined }
|
|
60
53
|
: group.label === "Admin"
|
|
61
54
|
? { ...group, icon: Settings }
|
|
62
55
|
: group.label === "Activity"
|
|
@@ -72,9 +65,13 @@ export function useWorkbenchState(chatRoute) {
|
|
|
72
65
|
const chatOnly = chatRoute && !panelOpen;
|
|
73
66
|
const location = useLocation();
|
|
74
67
|
const { navGroups, workspaceGroups, staticNavigationGroups } = useWorkbenchNavigation();
|
|
75
|
-
const routeItem = useMemo(() =>
|
|
76
|
-
|
|
77
|
-
|
|
68
|
+
const routeItem = useMemo(() => {
|
|
69
|
+
const item = findNavItem(navGroups, location.pathname + location.search)?.item;
|
|
70
|
+
return item &&
|
|
71
|
+
normalizeWorkbenchPath(item.to.split("?")[0]) === normalizeWorkbenchPath(location.pathname)
|
|
72
|
+
? item
|
|
73
|
+
: undefined;
|
|
74
|
+
}, [location.pathname, location.search, navGroups]);
|
|
78
75
|
const pageLabel = useAppStore((s) => s.navContext.label);
|
|
79
76
|
const entityId = routeItem?.meta?.spacesEntityId;
|
|
80
77
|
const chatWidth = useChatWidth();
|
|
@@ -108,7 +105,7 @@ export function useWorkbenchState(chatRoute) {
|
|
|
108
105
|
const openHistory = () => {
|
|
109
106
|
setHistoryOpen(true);
|
|
110
107
|
};
|
|
111
|
-
const historyShortcut = (_jsxs(Button, { variant: "ghost", size: "sm", onClick: openHistory, className: "h-9 w-fit gap-2 px-2 text-sm font-normal text-muted-foreground [@media(pointer:coarse)]:min-h-11", children: [_jsx(
|
|
108
|
+
const historyShortcut = (_jsxs(Button, { variant: "ghost", size: "sm", onClick: openHistory, className: "h-9 w-fit gap-2 px-2 text-sm font-normal text-muted-foreground [@media(pointer:coarse)]:min-h-11", children: [_jsx(MessagesSquare, { className: "size-4", "aria-hidden": true }), "Conversation history"] }));
|
|
112
109
|
const toggleNavigation = useSidebarStore((s) => s.toggleMobile);
|
|
113
110
|
useEffect(() => {
|
|
114
111
|
if (panelOpen) {
|
|
@@ -4,7 +4,7 @@ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuIte
|
|
|
4
4
|
import { ChatHomeStartersSlot } from "../components/chat-slots.js";
|
|
5
5
|
import { Layers } from "lucide-react";
|
|
6
6
|
export function WelcomeIntro({ navGroups, historyShortcut, }) {
|
|
7
|
-
return (_jsxs("div", { className: "mb-4 text-center", children: [_jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: "What would you like to get done?" }), _jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "Find information, create or edit content, and run actions across your spaces." }), _jsx("div", { className: "mx-auto mt-4 max-w-sm text-left", children: _jsx(ChatHomeStartersSlot, { priority: 10 }) }), _jsxs("div", { className: "mt-4 flex flex-wrap items-center justify-center gap-2", children: [historyShortcut, navGroups.some((group) => group.meta?.type === "spaces-workspaces" && group.createActions?.length) && (_jsx("div", { children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "sm", className: "h-
|
|
7
|
+
return (_jsxs("div", { className: "mb-4 text-center", children: [_jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: "What would you like to get done?" }), _jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "Find information, create or edit content, and run actions across your spaces." }), _jsx("div", { className: "mx-auto mt-4 max-w-sm text-left", children: _jsx(ChatHomeStartersSlot, { priority: 10 }) }), _jsxs("div", { className: "mt-4 flex flex-wrap items-center justify-center gap-2", children: [historyShortcut, navGroups.some((group) => group.meta?.type === "spaces-workspaces" && group.createActions?.length) && (_jsx("div", { children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "sm", className: "h-9 gap-2 px-2 text-sm font-normal text-muted-foreground [@media(pointer:coarse)]:min-h-11", children: [_jsx(Layers, { className: "size-4", "aria-hidden": "true" }), "Create a space"] }) }), _jsx(DropdownMenuContent, { align: "center", children: navGroups
|
|
8
8
|
.filter((group) => group.meta?.type === "spaces-workspaces")
|
|
9
9
|
.flatMap((group) => group.createActions ?? [])
|
|
10
10
|
.map((action) => (_jsx(DropdownMenuItem, { onSelect: () => action.handler(), children: action.label }, action.id))) })] }) }))] })] }));
|
|
@@ -101,7 +101,6 @@ export function WorkbenchStyles() {
|
|
|
101
101
|
}
|
|
102
102
|
.workbench-preview {
|
|
103
103
|
--workbench-header-height: 60px;
|
|
104
|
-
--sidebar: color-mix(in srgb, var(--background) 98.5%, var(--foreground) 1.5%);
|
|
105
104
|
background: var(--sidebar);
|
|
106
105
|
--workbench-outline: color-mix(in srgb, var(--sidebar-ring) 28%, transparent);
|
|
107
106
|
padding: 8px 8px 8px 0;
|
|
@@ -255,15 +254,14 @@ export function WorkbenchStyles() {
|
|
|
255
254
|
min-height: 32px;
|
|
256
255
|
gap: 8px;
|
|
257
256
|
}
|
|
258
|
-
[data-workspace-navigation] [data-nav-group-label="Spaces"] > :first-child,
|
|
259
257
|
.workbench-preview [data-sidebar-surface] nav > [data-nav-group-label]:first-child > div:has(> [data-nav-group-header]) {
|
|
260
258
|
padding-top: 0;
|
|
261
259
|
}
|
|
262
|
-
[data-workspace-navigation] [data-nav-group-label="
|
|
263
|
-
font-size:
|
|
260
|
+
[data-workspace-navigation] [data-nav-group-label="All spaces"] [data-nav-depth="0"] > button {
|
|
261
|
+
font-size: 14px;
|
|
264
262
|
font-weight: 600;
|
|
265
|
-
letter-spacing:
|
|
266
|
-
line-height:
|
|
263
|
+
letter-spacing: normal;
|
|
264
|
+
line-height: 20px;
|
|
267
265
|
}
|
|
268
266
|
[data-workspace-navigation] [data-nav-group-label="Recent chats"] > :first-child {
|
|
269
267
|
padding-top: 10px;
|
|
@@ -271,6 +269,38 @@ export function WorkbenchStyles() {
|
|
|
271
269
|
[data-workspace-navigation] [data-nav-group-label="Content"] {
|
|
272
270
|
margin-top: 0;
|
|
273
271
|
}
|
|
272
|
+
.workbench-preview [data-nav-group-label="All spaces"] > div:has(> [data-nav-group-header]) {
|
|
273
|
+
padding-top: 8px;
|
|
274
|
+
}
|
|
275
|
+
.workbench-preview [data-nav-group-label="All spaces"] [data-nav-group-header] {
|
|
276
|
+
height: 32px;
|
|
277
|
+
min-height: 32px;
|
|
278
|
+
padding-top: 0;
|
|
279
|
+
padding-bottom: 0;
|
|
280
|
+
}
|
|
281
|
+
.workbench-preview [data-nav-group-label="All spaces"] [data-nav-group-items] {
|
|
282
|
+
animation: none;
|
|
283
|
+
}
|
|
284
|
+
/* The first utility row shares the heading line in both scopes. */
|
|
285
|
+
.workbench-preview [data-sidebar-surface]:not([data-sidebar-collapsed]) nav:has(> [data-nav-group-label="Activity"]:first-child) {
|
|
286
|
+
padding-top: 8px;
|
|
287
|
+
}
|
|
288
|
+
.workbench-preview [data-sidebar-surface]:not([data-sidebar-collapsed]) [data-nav-group-label="Activity"] [data-nav-depth="0"] {
|
|
289
|
+
padding-left: 12px;
|
|
290
|
+
}
|
|
291
|
+
.workbench-preview [data-nav-group-label="Activity"] [data-nav-twisty-cell]:not(:has([data-nav-twisty])) {
|
|
292
|
+
display: none;
|
|
293
|
+
}
|
|
294
|
+
.workbench-preview[data-workspace-navigation]:not(:has([data-page-title-row])) [data-chat-empty-state] {
|
|
295
|
+
padding-top: 28px;
|
|
296
|
+
}
|
|
297
|
+
.workbench-preview[data-workspace-navigation] [data-preview-entity-header] > [data-entity-header-row] {
|
|
298
|
+
padding-top: 24px;
|
|
299
|
+
min-height: 76px;
|
|
300
|
+
}
|
|
301
|
+
.workbench-preview[data-workspace-navigation] [data-entity-header-identity]:not(:has([aria-label="Page location"])) {
|
|
302
|
+
padding-top: 18px;
|
|
303
|
+
}
|
|
274
304
|
|
|
275
305
|
[data-workspace-navigation] [data-sidebar-surface]:not([data-sidebar-collapsed]) [data-nav-group-label="Content"] button[data-nav-depth],
|
|
276
306
|
[data-workspace-navigation] [data-sidebar-surface]:not([data-sidebar-collapsed]) [data-nav-group-label="Content"] div[data-nav-depth] > button:not([data-nav-twisty]) {
|
|
@@ -280,6 +310,24 @@ export function WorkbenchStyles() {
|
|
|
280
310
|
left: calc(12px + var(--nav-depth, 0) * 16px);
|
|
281
311
|
}
|
|
282
312
|
|
|
313
|
+
@media (pointer: fine) {
|
|
314
|
+
.workbench-preview [data-sidebar-surface]:not([data-sidebar-collapsed]) [data-nav-depth] {
|
|
315
|
+
height: 32px;
|
|
316
|
+
min-height: 32px;
|
|
317
|
+
padding-top: 0;
|
|
318
|
+
padding-bottom: 0;
|
|
319
|
+
}
|
|
320
|
+
.workbench-preview [data-sidebar-surface]:not([data-sidebar-collapsed]) div[data-nav-depth] > button:not([data-nav-twisty]) {
|
|
321
|
+
height: 30px;
|
|
322
|
+
min-height: 30px;
|
|
323
|
+
padding-top: 0;
|
|
324
|
+
padding-bottom: 0;
|
|
325
|
+
}
|
|
326
|
+
.workbench-preview:not([data-workspace-navigation]) [data-sidebar-surface]:not([data-sidebar-collapsed]) div[data-nav-depth="0"] > button:not([data-nav-twisty]) {
|
|
327
|
+
min-height: 30px;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
283
331
|
@media (pointer: coarse) {
|
|
284
332
|
.workbench-preview [data-conversation-row],
|
|
285
333
|
.workbench-preview [data-sidebar-surface]:not([data-sidebar-collapsed]) [data-nav-depth] {
|
|
@@ -39,5 +39,5 @@ export function WorkbenchPreview({ page, chatOnly: chatRoute = false, }) {
|
|
|
39
39
|
}, children: [_jsx(WorkbenchChatHeader, { collapsed: collapsed, running: running, chatWidth: chatWidth, buttonClass: buttonClass, toggleNavigation: toggleNavigation, setCollapsed: setCollapsed, showHistory: showHistory, startChat: startChat, returnToChat: returnToChat, openHistory: openHistory, chatOnly: chatOnly, setContentCollapsed: setContentCollapsed }), !collapsed && showHistory && (_jsx(ConversationHistory, { groups: navGroups, workspaceId: workspaceId, onClose: returnToChat, showBack: true })), !chatWidth.compact && !collapsed && !contentCollapsed && (_jsx(ChatResizeHandle, { chatWidth: chatWidth })), _jsx("div", { className: "min-h-0 flex-1 flex-col", style: {
|
|
40
40
|
display: collapsed || showHistory ? "none" : "flex",
|
|
41
41
|
paddingBottom: spaciousChat && emptyChat && !historyOpen ? "clamp(32px, 10vh, 96px)" : undefined,
|
|
42
|
-
}, children: _jsx(ChatContent, { centerComposer: spaciousChat && emptyChat && !historyOpen, composerIntro: spaciousChat && emptyChat ? (_jsx(WelcomeIntro, { navGroups: navGroups, historyShortcut: emptyChatFooter })) : undefined, compactComposer: !spaciousChat,
|
|
42
|
+
}, children: _jsx(ChatContent, { centerComposer: spaciousChat && emptyChat && !historyOpen, composerIntro: spaciousChat && emptyChat ? (_jsx(WelcomeIntro, { navGroups: navGroups, historyShortcut: emptyChatFooter })) : undefined, compactComposer: !spaciousChat, starterSuggestions: [], emptyState: _jsx(ChatEmptyState, { pageLabel: pageLabel, showHomeStarters: !spaciousChat, children: emptyChatFooter }) }) })] }), _jsx(WorkbenchContentPane, { contentHidden: contentHidden, panelOpen: panelOpen, chatWidth: chatWidth, contentCollapsed: contentCollapsed, collapsed: collapsed, buttonClass: buttonClass, setCollapsed: setCollapsed, setContentCollapsed: setContentCollapsed, closePanel: closePanel, page: page }), contentCollapsed && !chatOnly && !chatWidth.compact && (_jsx("aside", { "aria-label": "Collapsed content", className: "flex w-11 shrink-0 flex-col items-center", style: { width: 44 }, children: _jsx("div", { className: "flex h-full w-full flex-col items-center", "data-chat-rail": true, children: _jsx("div", { className: "flex items-center justify-center", style: { height: 60 }, children: _jsx(TooltipIconButton, { tooltip: "Expand content", className: buttonClass, "aria-label": "Expand content", onClick: () => setContentCollapsed(false), children: _jsx(FileText, { size: 18 }) }) }) }) }))] })] })] }));
|
|
43
43
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iloveagents/foundry-web-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React agent UI core for Foundry UI — chat, composer, AG-UI adapter for assistant-ui, tool cards, panels, sidebar, theme runtime, and UI stores.",
|
|
6
6
|
"keywords": [
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
"recharts": "^3.10.1",
|
|
81
81
|
"remark-gfm": "^4.0.0",
|
|
82
82
|
"tailwind-merge": "^3.5.0",
|
|
83
|
-
"@iloveagents/foundry-agent": "^0.
|
|
84
|
-
"@iloveagents/foundry-web-primitives": "^0.
|
|
83
|
+
"@iloveagents/foundry-agent": "^0.31.0",
|
|
84
|
+
"@iloveagents/foundry-web-primitives": "^0.31.0"
|
|
85
85
|
},
|
|
86
86
|
"devDependencies": {
|
|
87
87
|
"@ag-ui/client": "^0.0.52",
|