@shutootaki/gwm
Version:
git worktree manager CLI
49 lines • 3.7 kB
JavaScript
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