UNPKG

@graphteon/juricode

Version:

We are forging the future with lines of digital steel

133 lines 8.62 kB
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime"; import React, { useState, useEffect } from 'react'; import { Box, Text, useInput, useApp } from 'ink'; import OpenHands from '../api/open-hands'; const RepositoriesTUI = ({ onBack, onSelectRepository }) => { const [repositories, setRepositories] = useState([]); const [filteredRepos, setFilteredRepos] = useState([]); const [selectedIndex, setSelectedIndex] = useState(0); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [searchMode, setSearchMode] = useState(false); const [searchTerm, setSearchTerm] = useState(''); const [showBranches, setShowBranches] = useState(false); const [branches, setBranches] = useState([]); const [selectedBranchIndex, setSelectedBranchIndex] = useState(0); const [loadingBranches, setLoadingBranches] = useState(false); const { exit } = useApp(); useEffect(() => { const fetchRepositories = async () => { try { setLoading(true); const repos = await OpenHands.retrieveUserGitRepositories(); setRepositories(repos); setFilteredRepos(repos); setError(null); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to fetch repositories'); } finally { setLoading(false); } }; fetchRepositories(); }, []); useEffect(() => { if (searchTerm) { const filtered = repositories.filter(repo => repo.full_name.toLowerCase().includes(searchTerm.toLowerCase())); setFilteredRepos(filtered); setSelectedIndex(0); } else { setFilteredRepos(repositories); } }, [searchTerm, repositories]); const fetchBranches = async (repo) => { try { setLoadingBranches(true); const repoBranches = await OpenHands.getRepositoryBranches(repo.full_name); setBranches(repoBranches); setSelectedBranchIndex(0); setShowBranches(true); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to fetch branches'); } finally { setLoadingBranches(false); } }; useInput((input, key) => { if (key.escape) { if (showBranches) { setShowBranches(false); setBranches([]); return; } if (searchMode) { setSearchMode(false); setSearchTerm(''); return; } onBack(); return; } if (loading || loadingBranches) return; if (searchMode) { if (key.return) { setSearchMode(false); return; } if (key.backspace || key.delete) { setSearchTerm(prev => prev.slice(0, -1)); return; } if (input && input.length === 1) { setSearchTerm(prev => prev + input); return; } return; } if (showBranches) { if (key.upArrow && selectedBranchIndex > 0) { setSelectedBranchIndex(selectedBranchIndex - 1); } if (key.downArrow && selectedBranchIndex < branches.length - 1) { setSelectedBranchIndex(selectedBranchIndex + 1); } if (key.return && branches.length > 0) { const selectedRepo = filteredRepos[selectedIndex]; const selectedBranch = branches[selectedBranchIndex].name; onSelectRepository(selectedRepo, selectedBranch); } return; } if (key.upArrow && selectedIndex > 0) { setSelectedIndex(selectedIndex - 1); } if (key.downArrow && selectedIndex < filteredRepos.length - 1) { setSelectedIndex(selectedIndex + 1); } if (key.return && filteredRepos.length > 0) { const selectedRepo = filteredRepos[selectedIndex]; fetchBranches(selectedRepo); } if (input === 's') { setSearchMode(true); } if (input === 'q') { exit(); } }); const truncateText = (text, maxLength) => { return text.length > maxLength ? text.substring(0, maxLength) + '...' : text; }; if (showBranches) { return (_jsxs(Box, { flexDirection: "column", height: "100%", children: [_jsx(Box, { borderStyle: "single", borderColor: "blue", paddingX: 1, children: _jsxs(Text, { color: "blue", bold: true, children: ["\uD83C\uDF3F Select Branch - ", filteredRepos[selectedIndex]?.full_name] }) }), _jsx(Box, { flexDirection: "column", flexGrow: 1, paddingX: 1, paddingY: 1, children: loadingBranches ? (_jsx(Box, { justifyContent: "center", alignItems: "center", height: "100%", children: _jsx(Text, { color: "yellow", children: "\u23F3 Loading branches..." }) })) : branches.length === 0 ? (_jsx(Box, { justifyContent: "center", alignItems: "center", height: "100%", children: _jsx(Text, { color: "gray", children: "No branches found." }) })) : (branches.map((branch, index) => (_jsx(Box, { marginBottom: 1, children: _jsx(Box, { borderStyle: "single", borderColor: index === selectedBranchIndex ? 'green' : 'gray', paddingX: 1, paddingY: 0, children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { color: index === selectedBranchIndex ? 'green' : 'white', bold: true, children: [index === selectedBranchIndex ? '▶ ' : ' ', branch.name, branch.protected && _jsx(Text, { color: "red", children: " \uD83D\uDD12" })] }) }), branch.last_push_date && (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "gray", children: "Last push: " }), _jsx(Text, { color: "blue", children: new Date(branch.last_push_date).toLocaleDateString() })] }))] }) }) }, branch.name)))) }), _jsx(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, children: _jsxs(Text, { color: "gray", children: [branches.length > 0 ? '↑↓ Navigate • Enter Select • ' : '', "ESC Back \u2022 Q Quit"] }) })] })); } return (_jsxs(Box, { flexDirection: "column", height: "100%", children: [_jsxs(Box, { borderStyle: "single", borderColor: "blue", paddingX: 1, children: [_jsx(Text, { color: "blue", bold: true, children: "\uD83D\uDCDA Browse Repositories" }), searchMode && (_jsxs(Text, { color: "yellow", children: [" - Search: ", searchTerm, "\u2588"] }))] }), _jsx(Box, { flexDirection: "column", flexGrow: 1, paddingX: 1, paddingY: 1, children: loading ? (_jsx(Box, { justifyContent: "center", alignItems: "center", height: "100%", children: _jsx(Text, { color: "yellow", children: "\u23F3 Loading repositories..." }) })) : error ? (_jsx(Box, { justifyContent: "center", alignItems: "center", height: "100%", children: _jsxs(Text, { color: "red", children: ["\u274C Error: ", error] }) })) : filteredRepos.length === 0 ? (_jsx(Box, { justifyContent: "center", alignItems: "center", height: "100%", children: _jsx(Text, { color: "gray", children: searchTerm ? `No repositories found matching "${searchTerm}"` : 'No repositories found.' }) })) : (filteredRepos.map((repo, index) => (_jsx(Box, { marginBottom: 1, children: _jsx(Box, { borderStyle: "single", borderColor: index === selectedIndex ? 'green' : 'gray', paddingX: 1, paddingY: 0, children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { color: index === selectedIndex ? 'green' : 'white', bold: true, children: [index === selectedIndex ? '▶ ' : ' ', repo.full_name, repo.stargazers_count && repo.stargazers_count > 0 && (_jsxs(Text, { color: "yellow", children: [" \u2605", repo.stargazers_count] }))] }) }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "gray", children: "Provider: " }), _jsx(Text, { color: "blue", children: repo.git_provider }), _jsx(Text, { color: "gray", children: " | " }), _jsx(Text, { color: repo.is_public ? 'green' : 'yellow', children: repo.is_public ? 'Public' : 'Private' })] })] }) }) }, repo.full_name)))) }), _jsx(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, children: _jsxs(Text, { color: "gray", children: [filteredRepos.length > 0 ? '↑↓ Navigate • Enter Select • ' : '', "S Search \u2022 ESC Back \u2022 Q Quit"] }) })] })); }; export default RepositoriesTUI; //# sourceMappingURL=RepositoriesTUI.js.map