875594d66d
- Add CommitPanel component for viewing changed files and committing - Show file status indicators (M/A/D/?) in file tree - Integrate git status with workspace for real-time updates - Add CSS styles for commit panel and status badges Part of git-control change implementation.
103 lines
2.6 KiB
TypeScript
103 lines
2.6 KiB
TypeScript
import { useState } from "react";
|
|
|
|
import { commitChanges } from "../api/git_repositories";
|
|
|
|
interface CommitPanelProps {
|
|
projectId: string;
|
|
repoId: string;
|
|
modified: string[];
|
|
added: string[];
|
|
deleted: string[];
|
|
untracked: string[];
|
|
onCommit: () => void;
|
|
}
|
|
|
|
export const CommitPanel = ({
|
|
projectId,
|
|
repoId,
|
|
modified,
|
|
added,
|
|
deleted,
|
|
untracked,
|
|
onCommit,
|
|
}: CommitPanelProps) => {
|
|
const [message, setMessage] = useState("");
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const allFiles = [...modified, ...added, ...deleted, ...untracked];
|
|
const hasChanges = allFiles.length > 0;
|
|
|
|
const handleCommit = async () => {
|
|
if (!message.trim()) {
|
|
setError("Please enter a commit message");
|
|
return;
|
|
}
|
|
setLoading(true);
|
|
setError(null);
|
|
try {
|
|
await commitChanges(projectId, repoId, message);
|
|
setMessage("");
|
|
onCommit();
|
|
} catch {
|
|
setError("Commit failed. Please try again.");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
if (!hasChanges) return null;
|
|
|
|
return (
|
|
<div className="commit-panel">
|
|
<h4>Changes</h4>
|
|
|
|
<div className="file-list">
|
|
{modified.map((file) => (
|
|
<div key={file} className="file-item modified">
|
|
<span className="file-status">M</span>
|
|
<span className="file-name">{file}</span>
|
|
</div>
|
|
))}
|
|
{added.map((file) => (
|
|
<div key={file} className="file-item added">
|
|
<span className="file-status">A</span>
|
|
<span className="file-name">{file}</span>
|
|
</div>
|
|
))}
|
|
{deleted.map((file) => (
|
|
<div key={file} className="file-item deleted">
|
|
<span className="file-status">D</span>
|
|
<span className="file-name">{file}</span>
|
|
</div>
|
|
))}
|
|
{untracked.map((file) => (
|
|
<div key={file} className="file-item untracked">
|
|
<span className="file-status">?</span>
|
|
<span className="file-name">{file}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className="commit-form">
|
|
<textarea
|
|
placeholder="Commit message"
|
|
value={message}
|
|
onChange={(e) => setMessage(e.target.value)}
|
|
rows={2}
|
|
className="commit-message-input"
|
|
/>
|
|
{error && <div className="commit-error">{error}</div>}
|
|
<button
|
|
onClick={handleCommit}
|
|
disabled={loading || !message.trim()}
|
|
className="commit-button"
|
|
type="button"
|
|
>
|
|
{loading ? "Committing..." : "Commit"}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|