Files
stack/apps/web/src/components/hud/WidgetRenderer.tsx
T

104 lines
2.6 KiB
TypeScript

/**
* Widget renderer - renders the appropriate widget component based on type
*/
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
import { WidgetWrapper } from "./WidgetWrapper";
import {
TasksWidget,
CalendarWidget,
QuickCaptureWidget,
AgentStatusWidget,
OrchestratorEventsWidget,
} from "@/components/widgets";
import type { WidgetPlacement } from "@mosaic/shared";
export interface WidgetRendererProps {
widget: WidgetPlacement;
isEditing?: boolean;
onRemove?: (widgetId: string) => void;
}
const WIDGET_COMPONENTS = {
tasks: TasksWidget,
calendar: CalendarWidget,
"quick-capture": QuickCaptureWidget,
"agent-status": AgentStatusWidget,
"orchestrator-events": OrchestratorEventsWidget,
};
const WIDGET_CONFIG = {
tasks: {
displayName: "Tasks",
description: "View and manage your tasks",
},
calendar: {
displayName: "Calendar",
description: "Upcoming events and schedule",
},
"quick-capture": {
displayName: "Quick Capture",
description: "Capture ideas and notes",
},
"agent-status": {
displayName: "Agent Status",
description: "View running agent sessions",
},
"orchestrator-events": {
displayName: "Orchestrator Events",
description: "Recent orchestration events and stream health",
},
};
export function WidgetRenderer({
widget,
isEditing = false,
onRemove,
}: WidgetRendererProps): React.JSX.Element {
// Extract widget type from ID by removing the trailing unique suffix
// (e.g., "agent-status-123" -> "agent-status").
const separatorIndex = widget.i.lastIndexOf("-");
const widgetType = (
separatorIndex > 0 ? widget.i.substring(0, separatorIndex) : widget.i
) as keyof typeof WIDGET_COMPONENTS;
const WidgetComponent = WIDGET_COMPONENTS[widgetType];
const config = WIDGET_CONFIG[widgetType] || { displayName: "Widget", description: "" };
if (!WidgetComponent) {
const wrapperProps = {
id: widget.i,
title: "Unknown Widget",
isEditing: isEditing,
...(onRemove && {
onRemove: (): void => {
onRemove(widget.i);
},
}),
};
return (
<WidgetWrapper {...wrapperProps}>
<div className="text-gray-500 text-sm">Widget type not found: {widgetType}</div>
</WidgetWrapper>
);
}
const wrapperProps = {
id: widget.i,
title: config.displayName,
isEditing: isEditing,
...(onRemove && {
onRemove: (): void => {
onRemove(widget.i);
},
}),
};
return (
<WidgetWrapper {...wrapperProps}>
<WidgetComponent id={widget.i} />
</WidgetWrapper>
);
}