Files
paseo/packages/app/src/screens/workspace/workspace-pane-content.tsx
T
Mohamed BoudraandGitHub 8b09846f98 feat(app): import-agent pill above draft composer (#833)
Surfaces the existing Import-agent sheet directly from the new-agent
draft composer, so users don't have to dig into the workspace header
menu. The pill renders only on draft tabs (gated by the prop being
provided) and reuses the existing WorkspaceImportSheet.
2026-05-09 17:33:14 +08:00

92 lines
2.6 KiB
TypeScript

import React, { useMemo, type ComponentType } from "react";
import invariant from "tiny-invariant";
import {
createPaneFocusContextValue,
PaneFocusProvider,
PaneProvider,
type PaneContextValue,
} from "@/panels/pane-context";
import { getPanelRegistration } from "@/panels/panel-registry";
import { ensurePanelsRegistered } from "@/panels/register-panels";
import type { WorkspaceTabDescriptor } from "@/screens/workspace/workspace-tabs-types";
export interface WorkspacePaneContentModel {
key: string;
Component: ComponentType;
paneContextValue: PaneContextValue;
}
export interface BuildWorkspacePaneContentModelInput {
tab: WorkspaceTabDescriptor;
normalizedServerId: string;
normalizedWorkspaceId: string;
onOpenTab: (target: WorkspaceTabDescriptor["target"]) => void;
onCloseCurrentTab: () => void;
onRetargetCurrentTab: (target: WorkspaceTabDescriptor["target"]) => void;
onOpenWorkspaceFile: (filePath: string) => void;
onOpenImportSheet: () => void;
}
export function buildWorkspacePaneContentModel({
tab,
normalizedServerId,
normalizedWorkspaceId,
onOpenTab,
onCloseCurrentTab,
onRetargetCurrentTab,
onOpenWorkspaceFile,
onOpenImportSheet,
}: BuildWorkspacePaneContentModelInput): WorkspacePaneContentModel {
ensurePanelsRegistered();
const registration = getPanelRegistration(tab.kind);
invariant(registration, `No panel registration for kind: ${tab.kind}`);
return {
key: `${normalizedServerId}:${normalizedWorkspaceId}:${tab.tabId}:${tab.kind}`,
Component: registration.component,
paneContextValue: {
serverId: normalizedServerId,
workspaceId: normalizedWorkspaceId,
tabId: tab.tabId,
target: tab.target,
openTab: onOpenTab,
closeCurrentTab: onCloseCurrentTab,
retargetCurrentTab: onRetargetCurrentTab,
openFileInWorkspace: onOpenWorkspaceFile,
openImportSheet: onOpenImportSheet,
},
};
}
export interface WorkspacePaneContentProps {
content: WorkspacePaneContentModel;
isWorkspaceFocused: boolean;
isPaneFocused: boolean;
onFocusPane?: () => void;
}
export function WorkspacePaneContent({
content,
isWorkspaceFocused,
isPaneFocused,
onFocusPane,
}: WorkspacePaneContentProps) {
const { Component, key, paneContextValue } = content;
const paneFocusValue = useMemo(
() =>
createPaneFocusContextValue({
isWorkspaceFocused,
isPaneFocused,
onFocusPane,
}),
[isPaneFocused, isWorkspaceFocused, onFocusPane],
);
return (
<PaneProvider value={paneContextValue}>
<PaneFocusProvider value={paneFocusValue}>
<Component key={key} />
</PaneFocusProvider>
</PaneProvider>
);
}