All files / frontend/src/components/Sidebar SiteWorkspaceSwitcher.tsx

3.84% Statements 1/26
0% Branches 0/12
0% Functions 0/6
4% Lines 1/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117                      1x                                                                                                                                                                                                                  
import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router';
import Select, { SelectChangeEvent } from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import ListItemText from '@mui/material/ListItemText';
import FolderIcon from '@mui/icons-material/Folder';
import Avatar from '@mui/material/Avatar';
import { styled } from '@mui/material/styles';
import service from '../../services/service';
import type { Workspace } from '../../../types';
 
const StyledAvatar = styled(Avatar)(({ theme }) => ({
  width: 28,
  height: 28,
  backgroundColor: theme.palette.background.paper,
  color: theme.palette.text.secondary,
  border: `1px solid ${theme.palette.divider}`,
}));
 
interface SiteWorkspaceSwitcherProps {
  currentSite?: string;
  currentWorkspace?: string;
}
 
/**
 * Workspace switcher for the current site.
 * Shows all workspaces available for the current site.
 */
function SiteWorkspaceSwitcher({
  currentSite = '',
  currentWorkspace = '',
}: SiteWorkspaceSwitcherProps) {
  const navigate = useNavigate();
  const [workspaces, setWorkspaces] = useState<Workspace[]>([]);
  const [loading, setLoading] = useState(true);
 
  useEffect(() => {
    const loadWorkspaces = async () => {
      if (!currentSite) {
        setLoading(false);
        return;
      }
 
      try {
        // Fetch workspaces for the current site
        const workspaceList = await service.api.listWorkspaces(currentSite);
        setWorkspaces(workspaceList);
      } catch (error) {
        console.error('Failed to load workspaces:', error);
      } finally {
        setLoading(false);
      }
    };
 
    loadWorkspaces();
  }, [currentSite]);
 
  const handleChange = (event: SelectChangeEvent) => {
    const workspaceKey = event.target.value;
    if (workspaceKey && currentSite) {
      navigate(`/sites/${encodeURIComponent(currentSite)}/workspaces/${encodeURIComponent(workspaceKey)}`);
    }
  };
 
  if (loading) {
    return (
      <Select value="" displayEmpty fullWidth size="small" disabled>
        <MenuItem value="">
          <ListItemText primary="Loading..." />
        </MenuItem>
      </Select>
    );
  }
 
  if (workspaces.length === 0) {
    return (
      <Select value="" displayEmpty fullWidth size="small" disabled>
        <MenuItem value="">
          <ListItemText primary="No workspaces" />
        </MenuItem>
      </Select>
    );
  }
 
  return (
    <Select
      value={currentWorkspace}
      onChange={handleChange}
      displayEmpty
      fullWidth
      size="small"
      sx={{
        '& .MuiSelect-select': {
          display: 'flex',
          alignItems: 'center',
          gap: 1,
        },
      }}
    >
      {workspaces.map((workspace) => (
        <MenuItem key={workspace.key} value={workspace.key}>
          <StyledAvatar>
            <FolderIcon sx={{ fontSize: '1rem' }} />
          </StyledAvatar>
          <ListItemText
            primary={workspace.key}
            // secondary={workspace.path}
            sx={{ ml: 1.5 }}
          />
        </MenuItem>
      ))}
    </Select>
  );
}
 
export default SiteWorkspaceSwitcher;