UNPKG

@shutootaki/gwm

Version:
49 lines 3.7 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { useMemo } from 'react'; import { Box, Text } from 'ink'; import { getOptimalColumnWidths } from '../utils/index.js'; import { getRepoRoot } from '../utils/git.js'; import { useTerminalWidth } from '../hooks/useTerminalWidth.js'; import { WorktreeRow } from './WorktreeRow.js'; import { loadConfig } from '../config.js'; /** * ワークツリー一覧をテーブル形式で表示する共通コンポーネント */ export const WorktreeTable = ({ worktrees, title = 'Worktrees', footer, }) => { // 現在のターミナル幅を取得 (必ず最初に呼び出す) const terminalWidth = useTerminalWidth(); // Git リポジトリのルート (不変) const repoRoot = useMemo(() => getRepoRoot(), []); // 設定ファイル (不変) const { worktree_base_path: WORKTREE_BASE_PATH } = loadConfig(); const BASE_TOKEN = '${B}'; // 統計情報をメモ化 const stats = useMemo(() => { return { total: worktrees.length, active: worktrees.filter((w) => w.isActive).length, main: worktrees.filter((w) => w.status === 'MAIN' && !w.isActive).length, other: worktrees.filter((w) => w.status === 'OTHER').length, }; }, [worktrees]); // 列幅計算(ターミナル幅依存) const columnWidths = useMemo(() => { const displayItems = worktrees.map((w) => { let pathStr; if (w.path.startsWith(WORKTREE_BASE_PATH)) { pathStr = `${BASE_TOKEN}/${w.path.substring(WORKTREE_BASE_PATH.length + 1)}`; } else if (w.path.startsWith(repoRoot)) { pathStr = w.path.substring(repoRoot.length + 1); } else { pathStr = w.path; } return { branch: w.branch, path: pathStr }; }); return getOptimalColumnWidths(displayItems, terminalWidth); }, [worktrees, repoRoot, terminalWidth, WORKTREE_BASE_PATH]); const isEmpty = worktrees.length === 0; return (_jsxs(Box, { flexDirection: "column", children: [isEmpty ? (_jsx(Text, { color: "yellow", children: "No worktrees found" })) : (_jsxs(_Fragment, { children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: title }), _jsxs(Text, { color: "gray", children: ["Total:", ' ', _jsx(Text, { color: "white", bold: true, children: stats.total }), ' ', "| Active:", ' ', _jsx(Text, { color: "yellow", bold: true, children: stats.active }), ' ', "| Main:", ' ', _jsx(Text, { color: "cyan", bold: true, children: stats.main }), ' ', "| Other:", ' ', _jsx(Text, { color: "white", bold: true, children: stats.other })] }), WORKTREE_BASE_PATH && (_jsxs(Text, { color: "gray", children: ['${B}', " = ", WORKTREE_BASE_PATH] }))] }) }), _jsx(Box, { children: _jsxs(Text, { color: "cyan", bold: true, children: [' STATUS'.padEnd(14), ' ', `BRANCH`.padEnd(columnWidths.branchWidth), ' ', `DIR_PATH`.padEnd(columnWidths.pathWidth), " ", 'HEAD'.padEnd(10)] }) }), _jsx(Box, { children: _jsxs(Text, { color: "gray", children: [' ══════'.padEnd(14), " ", '═'.repeat(columnWidths.branchWidth), ' ', '═'.repeat(columnWidths.pathWidth), " ", '══════════'.padEnd(10)] }) }), _jsx(Box, { flexDirection: "column", children: worktrees.map((wt, idx) => (_jsx(WorktreeRow, { worktree: wt, repoRoot: repoRoot, columnWidths: columnWidths }, idx))) })] })), footer && (_jsx(Box, { marginTop: 1, flexDirection: "column", children: footer }))] })); }; //# sourceMappingURL=WorktreeTable.js.map