together-code
Version:
AI-powered coding assistant that plans, then builds
113 lines (112 loc) • 5.53 kB
JavaScript
import React from 'react';
import { Box, Text, useInput } from 'ink';
const FilePermissionDialog = ({ files, existingFiles, onApprove, onReject, onApproveSelected }) => {
const [selectedIndex, setSelectedIndex] = React.useState(0);
const [selectedFiles, setSelectedFiles] = React.useState(new Set(files.map(f => f.path)));
useInput((input, key) => {
if (key.upArrow) {
setSelectedIndex(Math.max(0, selectedIndex - 1));
}
else if (key.downArrow) {
setSelectedIndex(Math.min(files.length - 1, selectedIndex + 1));
}
else if (input === ' ') {
// Toggle file selection
const filePath = files[selectedIndex].path;
const newSelected = new Set(selectedFiles);
if (newSelected.has(filePath)) {
newSelected.delete(filePath);
}
else {
newSelected.add(filePath);
}
setSelectedFiles(newSelected);
}
else if (key.return) {
if (selectedFiles.size === files.length) {
onApprove();
}
else {
onApproveSelected(files.filter(f => selectedFiles.has(f.path)));
}
}
else if (input.toLowerCase() === 'a') {
onApprove();
}
else if (input.toLowerCase() === 'n' || key.escape) {
onReject();
}
else if (input.toLowerCase() === 's') {
onApproveSelected(files.filter(f => selectedFiles.has(f.path)));
}
});
const getFileStatus = (filePath) => {
if (existingFiles.includes(filePath)) {
return { icon: '📝', status: 'MODIFY', color: 'yellow' };
}
else {
return { icon: '📄', status: 'CREATE', color: 'green' };
}
};
const getSelectionIcon = (filePath) => {
return selectedFiles.has(filePath) ? '✅' : '⬜';
};
return (React.createElement(Box, { flexDirection: "column", padding: 1 },
React.createElement(Box, { marginBottom: 1 },
React.createElement(Text, { color: "cyan", bold: true }, "\uD83D\uDD12 File Permission Required")),
React.createElement(Box, { marginBottom: 1 },
React.createElement(Text, { color: "white" }, "The following files will be created/modified:")),
React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, files.map((file, index) => {
const fileStatus = getFileStatus(file.path);
const isSelected = selectedIndex === index;
const selectionIcon = getSelectionIcon(file.path);
return (React.createElement(Box, { key: file.path, marginBottom: 1 },
React.createElement(Box, null,
React.createElement(Text, { color: isSelected ? 'cyan' : 'white' },
isSelected ? '► ' : ' ',
selectionIcon,
" ",
fileStatus.icon),
React.createElement(Text, { color: fileStatus.color, bold: true },
"[",
fileStatus.status,
"]"),
React.createElement(Text, { color: isSelected ? 'cyan' : 'white' },
" ",
file.path)),
isSelected && (React.createElement(Box, { flexDirection: "column", marginTop: 1, paddingLeft: 4 },
React.createElement(Text, { color: "gray", dimColor: true }, "Preview:"),
React.createElement(Box, { paddingLeft: 2 },
React.createElement(Text, { color: "gray" },
file.content.split('\n').slice(0, 5).join('\n'),
file.content.split('\n').length > 5 ? '\n...' : ''))))));
})),
React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
React.createElement(Text, { color: "white" },
"Selected: ",
selectedFiles.size,
"/",
files.length,
" files"),
React.createElement(Text, { color: "green" },
"New files: ",
files.filter(f => !existingFiles.includes(f.path) && selectedFiles.has(f.path)).length),
React.createElement(Text, { color: "yellow" },
"Modified files: ",
files.filter(f => existingFiles.includes(f.path) && selectedFiles.has(f.path)).length)),
React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
React.createElement(Text, { color: "cyan" }, "Navigation:"),
React.createElement(Text, { color: "gray" }, " \u2191/\u2193 Select file \u2022 SPACE Toggle selection")),
React.createElement(Box, { flexDirection: "column" },
React.createElement(Text, { color: "cyan" }, "Actions:"),
React.createElement(Text, { color: "green" }, " A - Approve all files"),
React.createElement(Text, { color: "blue" },
" S - Approve selected files only (",
selectedFiles.size,
")"),
React.createElement(Text, { color: "yellow" },
" ENTER - Approve ",
selectedFiles.size === files.length ? 'all' : 'selected'),
React.createElement(Text, { color: "red" }, " N/ESC - Reject and cancel"))));
};
export default FilePermissionDialog;