Implementation:Microsoft Autogen Studio TeamBuilder Sidebar
| Sources | Microsoft_Autogen |
|---|---|
| Domains | UI Components, Sidebar Navigation, Team Management, Gallery Integration |
| Last Updated | 2026-02-11 17:00 GMT |
Overview
Description
The Studio_TeamBuilder_Sidebar module provides a collapsible sidebar component for managing teams in AutoGen Studio. The sidebar features two tabs: "Recents" for recently created/edited teams, and "From Gallery" for browsing template teams from galleries. It includes functionality for creating, selecting, and deleting teams, with integration to the gallery system for template-based team creation.
Key features include:
- Two-Tab Interface - Switch between recent teams and gallery templates
- Team List Management - View, select, and delete recent teams
- Gallery Integration - Browse and use gallery teams as templates
- Collapsible Design - Expand/collapse sidebar to maximize workspace
- Local Storage Persistence - Remembers selected gallery across sessions
- Real-time Updates - Shows team metadata (participant count, timestamps)
The sidebar integrates with the gallery API, team management hooks, and local storage for a seamless user experience.
Usage
The sidebar is used in the team builder view to:
- Create new teams from gallery templates
- Switch between existing teams
- Delete unwanted teams
- Browse available gallery templates
- View team metadata and status
- Collapse to maximize canvas space
Code Reference
Source Location
python/packages/autogen-studio/frontend/src/components/views/teambuilder/sidebar.tsx
Repository: https://github.com/microsoft/autogen
Full path: /tmp/kapso_repo_2mr4n2g4/python/packages/autogen-studio/frontend/src/components/views/teambuilder/sidebar.tsx
Signature
interface TeamSidebarProps {
isOpen: boolean;
teams: Team[];
currentTeam: Team | null;
onToggle: () => void;
onSelectTeam: (team: Team) => void;
onCreateTeam: (team: Team) => void;
onEditTeam: (team: Team) => void;
onDeleteTeam: (teamId: number) => void;
isLoading?: boolean;
selectedGallery: Gallery | null;
setSelectedGallery: (gallery: Gallery) => void;
}
export const TeamSidebar: React.FC<TeamSidebarProps>
Import
import { TeamSidebar } from './sidebar';
import type { Team, Gallery } from '../../types/datamodel';
I/O Contract
Inputs
TeamSidebarProps:
- isOpen - Boolean controlling sidebar visibility
- teams - Team[] array of recent teams to display
- currentTeam - Team | null currently selected team (highlighted)
- onToggle - Function called when collapse/expand button clicked
- onSelectTeam - Function called when team clicked:
(team: Team) => void - onCreateTeam - Function called when creating new team:
(team: Team) => void - onEditTeam - Function called when editing team:
(team: Team) => void - onDeleteTeam - Function called when deleting team:
(teamId: number) => void - isLoading - Optional boolean showing loading state (default: false)
- selectedGallery - Gallery | null currently selected gallery
- setSelectedGallery - Function to update selected gallery:
(gallery: Gallery) => void
Outputs
Rendered Elements:
Collapsed State:
- Toggle button with team count tooltip
- New team button icon
Expanded State:
- Header with team count badge and close button
- "New Team" button (disabled if no gallery selected)
- Two tabs: "Recents" and "From Gallery"
- Recent teams list with:
- Team name and component type badge
- Agent count display
- Relative timestamp
- Delete button (on hover)
- Gallery templates list with:
- Gallery selector dropdown
- Template team cards
- "Use as template" button (on hover)
User Actions:
- onToggle() - Sidebar expanded/collapsed
- onSelectTeam(team) - Team selected from recents
- onCreateTeam(team) - New team created (from button or template)
- onDeleteTeam(teamId) - Team deleted from recents
- setSelectedGallery(gallery) - Gallery selection changed
Side Effects:
- Fetches galleries on mount using GalleryAPI
- Persists selected gallery ID to localStorage:
selectedGalleryId_{userId} - Shows success message when template used:
"team_name added to Recents" - Switches to "recent" tab after creating team from gallery
Usage Examples
Example 1: Basic Sidebar Integration
import { TeamSidebar } from './sidebar';
import { useState } from 'react';
import type { Team, Gallery } from '../../types/datamodel';
function TeamBuilderView() {
const [isSidebarOpen, setIsSidebarOpen] = useState(true);
const [teams, setTeams] = useState<Team[]>([]);
const [currentTeam, setCurrentTeam] = useState<Team | null>(null);
const [selectedGallery, setSelectedGallery] = useState<Gallery | null>(null);
const handleCreateTeam = (newTeam: Team) => {
// Add to teams list and select it
setTeams([...teams, newTeam]);
setCurrentTeam(newTeam);
};
const handleDeleteTeam = (teamId: number) => {
setTeams(teams.filter(t => t.id !== teamId));
if (currentTeam?.id === teamId) {
setCurrentTeam(null);
}
};
return (
<div className="flex h-screen">
<TeamSidebar
isOpen={isSidebarOpen}
teams={teams}
currentTeam={currentTeam}
onToggle={() => setIsSidebarOpen(!isSidebarOpen)}
onSelectTeam={setCurrentTeam}
onCreateTeam={handleCreateTeam}
onEditTeam={(team) => console.log('Edit', team)}
onDeleteTeam={handleDeleteTeam}
selectedGallery={selectedGallery}
setSelectedGallery={setSelectedGallery}
/>
<div className="flex-1">
{/* Main canvas area */}
</div>
</div>
);
}
Example 2: Creating Teams from Gallery Templates
import { TeamSidebar } from './sidebar';
import { Component, TeamConfig } from '../../types/datamodel';
function TeamBuilderWithGallery() {
const [selectedGallery, setSelectedGallery] = useState<Gallery | null>(null);
const handleCreateTeam = (newTeam: Team) => {
// Team structure when created from gallery:
// newTeam.component is the gallery team with modified label
const teamConfig = newTeam.component as Component<TeamConfig>;
console.log('Creating team:', teamConfig.label);
console.log('Participants:', teamConfig.config.participants.length);
// Send to API to persist
teamAPI.createTeam(newTeam).then(savedTeam => {
console.log('Team saved with ID:', savedTeam.id);
});
};
return (
<TeamSidebar
isOpen={true}
teams={[]}
currentTeam={null}
onToggle={() => {}}
onSelectTeam={() => {}}
onCreateTeam={handleCreateTeam}
onEditTeam={() => {}}
onDeleteTeam={() => {}}
selectedGallery={selectedGallery}
setSelectedGallery={setSelectedGallery}
/>
);
}
Example 3: Handling Team Selection and Metadata
import { TeamSidebar } from './sidebar';
import { getRelativeTimeString } from '../atoms';
function TeamManager() {
const [teams, setTeams] = useState<Team[]>([
{
id: 1,
component: {
component_type: 'team',
label: 'Customer Support Team',
config: {
participants: [/* 3 agents */],
},
},
updated_at: '2026-02-11T10:30:00Z',
},
]);
const handleSelectTeam = (team: Team) => {
console.log('Selected:', team.component.label);
console.log('Agents:', team.component.config?.participants?.length || 0);
console.log('Last updated:', getRelativeTimeString(team.updated_at));
// Load team into canvas
loadTeamToCanvas(team);
};
return (
<TeamSidebar
isOpen={true}
teams={teams}
currentTeam={teams[0]}
onToggle={() => {}}
onSelectTeam={handleSelectTeam}
onCreateTeam={() => {}}
onEditTeam={() => {}}
onDeleteTeam={() => {}}
selectedGallery={null}
setSelectedGallery={() => {}}
/>
);
}
Example 4: Gallery Integration with Local Storage
import { TeamSidebar } from './sidebar';
import { getLocalStorage, setLocalStorage } from '../../utils/utils';
import { useContext, useEffect } from 'react';
import { appContext } from '../../../hooks/provider';
function GalleryAwareSidebar() {
const { user } = useContext(appContext);
const [selectedGallery, setSelectedGallery] = useState<Gallery | null>(null);
// The sidebar automatically handles this, but here's how it works:
// On gallery selection, it saves to localStorage
const handleGallerySelect = (gallery: Gallery) => {
setSelectedGallery(gallery);
// Saved by sidebar internally
if (user?.id) {
setLocalStorage(`selectedGalleryId_${user.id}`, gallery.id);
}
};
// On mount, it restores from localStorage
useEffect(() => {
if (user?.id) {
const savedGalleryId = getLocalStorage(`selectedGalleryId_${user.id}`);
if (savedGalleryId) {
// Fetch and set gallery
galleryAPI.getGallery(savedGalleryId).then(setSelectedGallery);
}
}
}, [user?.id]);
return (
<TeamSidebar
isOpen={true}
teams={[]}
currentTeam={null}
onToggle={() => {}}
onSelectTeam={() => {}}
onCreateTeam={() => {}}
onEditTeam={() => {}}
onDeleteTeam={() => {}}
selectedGallery={selectedGallery}
setSelectedGallery={handleGallerySelect}
/>
);
}
Example 5: Responsive Sidebar with Loading States
import { TeamSidebar } from './sidebar';
import { useState, useEffect } from 'react';
function ResponsiveTeamBuilder() {
const [isOpen, setIsOpen] = useState(true);
const [isLoading, setIsLoading] = useState(true);
const [teams, setTeams] = useState<Team[]>([]);
useEffect(() => {
// Fetch teams
setIsLoading(true);
teamAPI.listTeams().then(data => {
setTeams(data);
setIsLoading(false);
});
}, []);
// Auto-collapse on mobile
useEffect(() => {
const handleResize = () => {
if (window.innerWidth < 768) {
setIsOpen(false);
}
};
window.addEventListener('resize', handleResize);
handleResize();
return () => window.removeEventListener('resize', handleResize);
}, []);
return (
<TeamSidebar
isOpen={isOpen}
teams={teams}
currentTeam={null}
onToggle={() => setIsOpen(!isOpen)}
onSelectTeam={() => {}}
onCreateTeam={() => {}}
onEditTeam={() => {}}
onDeleteTeam={() => {}}
isLoading={isLoading}
selectedGallery={null}
setSelectedGallery={() => {}}
/>
);
}
Related Pages
- Studio_Builder_Store - State management for team builder
- Studio_Builder_Nodes - Node components for graph visualization
- Gallery_API - API client for fetching galleries
- Types_Datamodel - Team and Gallery type definitions
- Utils - Local storage utilities