reduce api | version control

This commit is contained in:
taDuc
2026-04-19 00:13:22 +07:00
parent c88a6497f7
commit bc98830871
9 changed files with 1141 additions and 449 deletions

View File

@@ -9,8 +9,42 @@ type Props = {
setMode: (mode: Mode) => void;
entityStatus?: string | null;
onUndo: () => void;
onSave: () => void;
onCommit: () => void;
onSubmit: () => void;
onRestoreCommit: (commitId: string) => void;
isSaving: boolean;
isSubmitting: boolean;
isOpeningSection: boolean;
sectionTitle: string;
sectionStatus: string;
selectedSectionId: string;
editorUserId: string;
sectionOptions: Array<{
id: string;
title: string;
state?: {
status?: string;
};
}>;
newSectionTitle: string;
commitTitle: string;
commitNote: string;
onEditorUserIdChange: (userId: string) => void;
onSelectedSectionIdChange: (sectionId: string) => void;
onNewSectionTitleChange: (title: string) => void;
onCommitTitleChange: (title: string) => void;
onCommitNoteChange: (note: string) => void;
onOpenSection: () => void;
onCreateSection: () => void;
commitCount: number;
latestCommitLabel: string | null;
commits: Array<{
id: string;
commit_no: number;
kind: string;
created_at: string;
title: string | null;
}>;
changesCount: number;
undoStack: UndoAction[];
createdEntities: Array<{
@@ -31,8 +65,30 @@ export default function Editor({
setMode,
entityStatus,
onUndo,
onSave,
onCommit,
onSubmit,
onRestoreCommit,
isSaving,
isSubmitting,
isOpeningSection,
sectionTitle,
sectionStatus,
selectedSectionId,
editorUserId,
sectionOptions,
newSectionTitle,
commitTitle,
commitNote,
onEditorUserIdChange,
onSelectedSectionIdChange,
onNewSectionTitleChange,
onCommitTitleChange,
onCommitNoteChange,
onOpenSection,
onCreateSection,
commitCount,
latestCommitLabel,
commits,
changesCount,
undoStack,
createdEntities,
@@ -83,6 +139,124 @@ export default function Editor({
}}
>
<h3 style={{ marginBottom: "10px" }}>Editor</h3>
<div
style={{
marginBottom: "12px",
padding: "10px",
background: "#0b1220",
borderRadius: "6px",
border: "1px solid #1f2937",
fontSize: "12px",
color: "#cbd5e1",
}}
>
<div style={{ color: "white", fontWeight: 600 }}>{sectionTitle}</div>
<div style={{ marginTop: "4px" }}>Status: {sectionStatus}</div>
<div>Commits: {commitCount}</div>
<div>{latestCommitLabel || "Chưa có commit"}</div>
</div>
<div
style={{
marginBottom: "12px",
padding: "10px",
background: "#0b1220",
borderRadius: "6px",
border: "1px solid #1f2937",
fontSize: "12px",
color: "#cbd5e1",
}}
>
<div style={{ marginBottom: "8px", fontWeight: 600, color: "white" }}>
Section
</div>
<input
value={editorUserId}
onChange={(event) => onEditorUserIdChange(event.target.value)}
placeholder="User ID"
style={{
width: "100%",
marginBottom: "8px",
padding: "7px",
borderRadius: "4px",
border: "1px solid #334155",
background: "#111827",
color: "white",
boxSizing: "border-box",
}}
disabled={isOpeningSection}
/>
<select
value={selectedSectionId}
onChange={(event) => onSelectedSectionIdChange(event.target.value)}
style={{
width: "100%",
padding: "7px",
borderRadius: "4px",
border: "1px solid #334155",
background: "#111827",
color: "white",
}}
disabled={isOpeningSection}
>
{sectionOptions.length === 0 ? (
<option value="">Chưa section</option>
) : null}
{sectionOptions.map((section) => (
<option key={section.id} value={section.id}>
{section.title} {section.state?.status ? `(${section.state.status})` : ""}
</option>
))}
</select>
<button
style={{
width: "100%",
marginTop: "8px",
padding: "8px",
borderRadius: "4px",
border: "none",
cursor: isOpeningSection || !selectedSectionId ? "not-allowed" : "pointer",
background: isOpeningSection || !selectedSectionId ? "#555" : "#2563eb",
color: "white",
}}
onClick={onOpenSection}
disabled={isOpeningSection || !selectedSectionId}
>
Mở section
</button>
<input
value={newSectionTitle}
onChange={(event) => onNewSectionTitleChange(event.target.value)}
placeholder="Tên section mới"
style={{
width: "100%",
marginTop: "10px",
padding: "7px",
borderRadius: "4px",
border: "1px solid #334155",
background: "#111827",
color: "white",
boxSizing: "border-box",
}}
disabled={isOpeningSection}
/>
<button
style={{
width: "100%",
marginTop: "8px",
padding: "8px",
borderRadius: "4px",
border: "none",
cursor: isOpeningSection || !newSectionTitle.trim() ? "not-allowed" : "pointer",
background: isOpeningSection || !newSectionTitle.trim() ? "#555" : "#0f766e",
color: "white",
}}
onClick={onCreateSection}
disabled={isOpeningSection || !newSectionTitle.trim()}
>
Tạo mở section
</button>
</div>
<button
style={getButtonStyle("draw")}
@@ -168,10 +342,10 @@ export default function Editor({
</div>
) : null}
<div style={{ marginTop: "12px", display: "flex", gap: "8px" }}>
<div style={{ marginTop: "12px" }}>
<button
style={{
flex: 1,
width: "100%",
padding: "8px",
borderRadius: "4px",
border: "none",
@@ -183,22 +357,125 @@ export default function Editor({
>
Undo
</button>
<button
style={{
flex: 1,
padding: "8px",
borderRadius: "4px",
border: "none",
cursor: isSaving ? "not-allowed" : "pointer",
background: isSaving ? "#555" : "#3b82f6",
color: "white",
opacity: changesCount === 0 ? 0.6 : 1,
}}
onClick={onSave}
disabled={isSaving || changesCount === 0}
>
Save ({changesCount})
</button>
</div>
<input
value={commitTitle}
onChange={(event) => onCommitTitleChange(event.target.value)}
placeholder="Commit title"
disabled={isSaving || isSubmitting || sectionStatus === "submitted"}
style={{
width: "100%",
marginTop: "8px",
padding: "7px",
borderRadius: "4px",
border: "1px solid #334155",
background: "#111827",
color: "white",
boxSizing: "border-box",
}}
/>
<textarea
value={commitNote}
onChange={(event) => onCommitNoteChange(event.target.value)}
placeholder="Commit note"
disabled={isSaving || isSubmitting || sectionStatus === "submitted"}
rows={3}
style={{
width: "100%",
marginTop: "8px",
padding: "7px",
borderRadius: "4px",
border: "1px solid #334155",
background: "#111827",
color: "white",
boxSizing: "border-box",
resize: "vertical",
fontFamily: "inherit",
}}
/>
<button
style={{
width: "100%",
marginTop: "8px",
padding: "8px",
borderRadius: "4px",
border: "none",
cursor: isSaving || isSubmitting || sectionStatus === "submitted" ? "not-allowed" : "pointer",
background: isSaving || isSubmitting || sectionStatus === "submitted" ? "#555" : "#0f766e",
color: "white",
}}
onClick={onCommit}
disabled={isSaving || isSubmitting || sectionStatus === "submitted"}
>
Commit ({changesCount})
</button>
<button
style={{
width: "100%",
marginTop: "8px",
padding: "8px",
borderRadius: "4px",
border: "none",
cursor: isSubmitting || commitCount === 0 || sectionStatus === "submitted" ? "not-allowed" : "pointer",
background: isSubmitting || commitCount === 0 || sectionStatus === "submitted" ? "#555" : "#16a34a",
color: "white",
opacity: commitCount === 0 ? 0.6 : 1,
}}
onClick={onSubmit}
disabled={isSubmitting || commitCount === 0 || sectionStatus === "submitted"}
>
Submit
</button>
<div
style={{
marginTop: "16px",
padding: "10px",
background: "#0b1220",
borderRadius: "6px",
border: "1px solid #1f2937",
}}
>
<div style={{ marginBottom: "8px", fontWeight: 600, fontSize: "14px" }}>
Commit history
</div>
{commits.length === 0 ? (
<div style={{ color: "#64748b", fontSize: "12px" }}>
Chưa commit
</div>
) : (
<ul style={{ listStyle: "none", margin: 0, padding: 0, fontSize: "12px" }}>
{commits.slice(0, 8).map((commit) => (
<li
key={commit.id}
style={{
padding: "6px 0",
borderBottom: "1px solid #1f2937",
color: "#e2e8f0",
}}
>
<div>
#{commit.commit_no} {commit.kind}
</div>
<button
style={{
marginTop: "4px",
padding: "4px 6px",
borderRadius: "4px",
border: "none",
background: "#334155",
color: "white",
cursor: isSaving || isSubmitting ? "not-allowed" : "pointer",
}}
onClick={() => onRestoreCommit(commit.id)}
disabled={isSaving || isSubmitting}
>
Restore
</button>
</li>
))}
</ul>
)}
</div>
<div
@@ -265,11 +542,11 @@ export default function Editor({
)}
<div style={{ fontSize: "13px", color: "#cbd5e1", marginBottom: "6px" }}>
Geometries mới chưa lưu ({createdGeometries.length})
Geometries mới chưa commit ({createdGeometries.length})
</div>
{createdGeometries.length === 0 ? (
<div style={{ color: "#64748b", fontSize: "12px" }}>
Chưa geometry mới chờ save
Chưa geometry mới chờ commit
</div>
) : (
<ul style={{ listStyle: "none", margin: 0, padding: 0, fontSize: "12px" }}>