Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 88 additions & 6 deletions apps/mesh/src/web/layouts/agent-shell-layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,14 @@ import { StudioSidebarMobile } from "@/web/components/sidebar";
import { useSidebar } from "@deco/ui/components/sidebar.tsx";
import { Sheet, SheetContent, SheetTitle } from "@deco/ui/components/sheet.tsx";
import { useIsMobile } from "@deco/ui/hooks/use-mobile.ts";
import { AlertCircle, Loading01, Menu01 } from "@untitledui/icons";
import {
AlertCircle,
Edit05,
Loading01,
Menu01,
MessageCircle01,
} from "@untitledui/icons";
import { cn } from "@deco/ui/lib/utils.js";
import {
getWellKnownDecopilotVirtualMCP,
SELF_MCP_ALIAS_ID,
Expand All @@ -58,6 +65,7 @@ import { useOptionalTasksPanelState } from "@/web/hooks/use-tasks-panel-state";
import { Toolbar } from "./toolbar";
import { ChatMainPanelGroup } from "./chat-main-panel-group";
import { ToggleButtons } from "./toggle-buttons";
import { MainPanelContent } from "@/web/layouts/main-panel-tabs";
import { MainPanelTabsBar } from "@/web/layouts/main-panel-tabs/main-panel-tabs-bar";
import { VirtualMcpHeaderInfo } from "../../views/virtual-mcp/header-info.tsx";
import { VmEventsProvider } from "@/web/components/vm/hooks/vm-events-context.tsx";
Expand Down Expand Up @@ -118,17 +126,58 @@ function NewTaskBridge({
return null;
}

function MobileToolbar({ onOpenSidebar }: { onOpenSidebar: () => void }) {
function MobileToolbar({
onOpenSidebar,
virtualMcpId,
taskId,
mainOpen,
onToggleMain,
onNewTask,
}: {
onOpenSidebar: () => void;
virtualMcpId: string;
taskId: string;
mainOpen: boolean;
onToggleMain: () => void;
onNewTask: () => void;
}) {
return (
<div className="shrink-0 flex items-center justify-between px-3 h-12 bg-background border-b border-border">
<div className="shrink-0 flex items-center gap-1 px-2 h-12 bg-background border-b border-border">
<button
type="button"
onClick={onOpenSidebar}
className="flex size-8 items-center justify-center rounded-md text-foreground/60 hover:bg-accent hover:text-foreground transition-colors"
className="flex size-8 shrink-0 items-center justify-center rounded-md text-foreground/60 hover:bg-accent hover:text-foreground transition-colors"
aria-label="Open menu"
>
<Menu01 size={20} />
</button>
<div className="flex-1 min-w-0 overflow-x-auto [scrollbar-width:none]">
<MainPanelTabsBar virtualMcpId={virtualMcpId} taskId={taskId} />
</div>
<div className="flex items-center gap-0.5 shrink-0">
<button
type="button"
onClick={onToggleMain}
aria-pressed={!mainOpen}
className={cn(
"flex size-7 shrink-0 items-center justify-center rounded-md transition-colors",
!mainOpen
? "bg-accent text-foreground"
: "text-foreground/60 hover:bg-accent hover:text-foreground",
)}
title="Chat"
>
<MessageCircle01 size={16} />
</button>
<button
type="button"
onClick={onNewTask}
className="flex size-7 shrink-0 items-center justify-center rounded-md text-foreground/60 hover:bg-accent hover:text-foreground transition-colors"
title="New task"
>
<Edit05 size={16} />
</button>
</div>
</div>
);
}
Expand Down Expand Up @@ -382,9 +431,42 @@ function AgentInsetProvider() {
onNewTaskRef={onNewTask}
createNewTask={layout.createNewTask}
/>
<MobileToolbar onOpenSidebar={() => setMobileSidebarOpen(true)} />
<MobileToolbar
onOpenSidebar={() => setMobileSidebarOpen(true)}
virtualMcpId={chatVirtualMcpId}
taskId={layout.taskId}
mainOpen={layout.mainOpen}
onToggleMain={layout.toggleMain}
onNewTask={layout.createNewTask}
/>
<div className="flex-1 min-h-0 overflow-hidden">
<ActiveTaskBoundary />
{layout.mainOpen ? (
<ErrorBoundary
fallback={
<div className="flex-1 flex items-center justify-center text-sm text-muted-foreground">
Something went wrong. Try refreshing.
</div>
}
>
<Suspense
fallback={
<div className="h-full flex items-center justify-center">
<Loading01
size={20}
className="animate-spin text-muted-foreground"
/>
</div>
}
>
<MainPanelContent
taskId={layout.taskId}
virtualMcpId={chatVirtualMcpId}
/>
</Suspense>
</ErrorBoundary>
) : (
<ActiveTaskBoundary />
)}
</div>
{mobileSidebarSheet}
</VmEventsBridge>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export function MainPanelTabsBar({
};

return (
<div className="flex items-center min-w-0 ml-auto gap-0.5">
<div className="flex items-center min-w-0 gap-0.5">
{visible.map((tab) => (
<HeaderTabButton
key={tab.id}
Expand Down
11 changes: 11 additions & 0 deletions apps/mesh/src/web/layouts/org-home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,20 @@
* optional-context fallback.
*/

import { useIsMobile } from "@deco/ui/hooks/use-mobile.ts";
import { HomePage } from "@/web/layouts/home-page";

export default function OrgHome() {
const isMobile = useIsMobile();

if (isMobile) {
return (
<div className="flex-1 min-h-0 flex flex-col bg-background overflow-hidden">
<HomePage />
</div>
);
}

return (
<div className="flex-1 min-h-0 p-1.5 overflow-hidden">
<div className="flex h-full flex-col bg-background overflow-hidden card-shadow rounded-[0.75rem]">
Expand Down
54 changes: 49 additions & 5 deletions apps/mesh/src/web/layouts/org-shell-layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ import {
SidebarInset,
SidebarLayout,
SidebarProvider,
useSidebar,
} from "@deco/ui/components/sidebar.tsx";
import { useIsMobile } from "@deco/ui/hooks/use-mobile.ts";
import { Loading01 } from "@untitledui/icons";
import { Sheet, SheetContent, SheetTitle } from "@deco/ui/components/sheet.tsx";
import { Loading01, Menu01 } from "@untitledui/icons";
import { Outlet, useParams } from "@tanstack/react-router";
import { StudioSidebar } from "@/web/components/sidebar";
import { StudioSidebar, StudioSidebarMobile } from "@/web/components/sidebar";
import { ChatPrefsProvider } from "@/web/components/chat/context";
import { TasksPanelStateProvider } from "@/web/hooks/use-tasks-panel-state";
import { Toolbar } from "@/web/layouts/agent-shell-layout/toolbar";
import { TasksPanelColumn } from "@/web/layouts/agent-shell-layout/tasks-panel-column";
import { TasksPanel } from "@/web/layouts/tasks-panel";

function RouteFallback() {
return (
Expand All @@ -30,6 +33,44 @@ function RouteFallback() {
);
}

function MobileHomeToolbar() {
const { setOpenMobile, openMobile } = useSidebar();
return (
<>
<div className="shrink-0 flex items-center px-2 h-12 bg-background border-b border-border">
<button
type="button"
onClick={() => setOpenMobile(true)}
className="flex size-8 shrink-0 items-center justify-center rounded-md text-foreground/60 hover:bg-accent hover:text-foreground transition-colors"
aria-label="Open menu"
>
<Menu01 size={20} />
</button>
</div>
<Sheet open={openMobile} onOpenChange={setOpenMobile}>
<SheetContent
side="left"
hideCloseButton
className="w-[calc(100vw-3rem)] sm:max-w-md! p-0"
>
<SheetTitle className="sr-only">Navigation</SheetTitle>
<div className="flex h-full">
<div
className="w-14 shrink-0 bg-sidebar flex flex-col items-center border-r border-border overflow-y-auto group/sidebar"
data-state="collapsed"
>
<StudioSidebarMobile onClose={() => setOpenMobile(false)} />
</div>
<div className="flex-1 min-w-0 overflow-hidden">
<TasksPanel />
</div>
</div>
</SheetContent>
</Sheet>
</>
);
}

export default function OrgShellLayout() {
const isMobile = useIsMobile();
const params = useParams({ strict: false }) as { taskId?: string };
Expand Down Expand Up @@ -57,9 +98,12 @@ export default function OrgShellLayout() {
<ChatPrefsProvider>
<TasksPanelStateProvider>
{isMobile ? (
<Suspense fallback={<RouteFallback />}>
<Outlet />
</Suspense>
<>
{!hasTaskRoute && <MobileHomeToolbar />}
<Suspense fallback={<RouteFallback />}>
<Outlet />
</Suspense>
</>
) : (
<Toolbar>
<Toolbar.Header>
Expand Down
Loading