mirror of
https://github.com/christianvidalwolf-prog/Craze-Data-check.git
synced 2026-08-03 14:35:23 +02:00
feat: revert individual pending changes from TopBar dropdown
- pendingRows now stores originalData + newData per article so changes can be individually reverted to their pre-edit state - TopBar Save button becomes a split button: left saves all, right opens a dropdown listing every pending change with article no + name - Each row in the dropdown has a Revert button that restores the original data locally and removes it from the pending queue - Dropdown closes automatically when all changes are saved/reverted or when clicking outside Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
acc1d06269
commit
a7d8dad36e
+31
-8
@@ -39,7 +39,7 @@ export default function App() {
|
||||
const [isLoadingDefault, setIsLoadingDefault] = useState(true);
|
||||
const [defaultLoadError, setDefaultLoadError] = useState<string | null>(null);
|
||||
const [rowStatuses, setRowStatuses] = useState<Record<string, string>>({});
|
||||
const [pendingRows, setPendingRows] = useState<Record<string, ExcelRow>>({});
|
||||
const [pendingRows, setPendingRows] = useState<Record<string, { rowIndex: number; originalData: ExcelRow; newData: ExcelRow; articleName: string }>>({});
|
||||
const [isSavingAll, setIsSavingAll] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -241,26 +241,47 @@ export default function App() {
|
||||
};
|
||||
|
||||
const handleSaveRow = (rowIndex: number, updatedRow: ExcelRow) => {
|
||||
// Update local UI state only — no Supabase call here.
|
||||
// Changes are queued in pendingRows and saved manually via handleSaveAll.
|
||||
const articleNo = String(updatedRow[COLUMNS.ARTICLE_NO]);
|
||||
const originalData = appState.data[rowIndex]; // Capture before update
|
||||
setAppState(prev => {
|
||||
const newData = [...prev.data];
|
||||
newData[rowIndex] = updatedRow;
|
||||
return { ...prev, data: newData, hasUnsavedChanges: true };
|
||||
});
|
||||
const articleNo = String(updatedRow[COLUMNS.ARTICLE_NO]);
|
||||
setPendingRows(prev => ({ ...prev, [articleNo]: updatedRow }));
|
||||
setPendingRows(prev => ({
|
||||
...prev,
|
||||
[articleNo]: {
|
||||
rowIndex,
|
||||
// Keep the very first originalData if already pending (re-edit case)
|
||||
originalData: prev[articleNo]?.originalData ?? originalData,
|
||||
newData: updatedRow,
|
||||
articleName: String(updatedRow[COLUMNS.ARTICLE_NAME] || articleNo),
|
||||
}
|
||||
}));
|
||||
setRowStatuses(prev => ({ ...prev, [articleNo]: 'pending' }));
|
||||
setEditingRowIndex(null);
|
||||
};
|
||||
|
||||
const handleRevertRow = (articleNo: string) => {
|
||||
const pending = pendingRows[articleNo];
|
||||
if (!pending) return;
|
||||
setAppState(prev => {
|
||||
const newData = [...prev.data];
|
||||
newData[pending.rowIndex] = pending.originalData;
|
||||
const stillPending = Object.keys(pendingRows).length > 1;
|
||||
return { ...prev, data: newData, hasUnsavedChanges: stillPending };
|
||||
});
|
||||
setPendingRows(prev => { const n = { ...prev }; delete n[articleNo]; return n; });
|
||||
setRowStatuses(prev => { const n = { ...prev }; delete n[articleNo]; return n; });
|
||||
};
|
||||
|
||||
const handleSaveAll = async () => {
|
||||
const entries = Object.entries(pendingRows) as [string, ExcelRow][];
|
||||
const entries = Object.entries(pendingRows) as [string, { rowIndex: number; originalData: ExcelRow; newData: ExcelRow; articleName: string }][];
|
||||
if (entries.length === 0) return;
|
||||
setIsSavingAll(true);
|
||||
let allSuccess = true;
|
||||
for (const [articleNo, rowData] of entries) {
|
||||
const success = await saveRowToSupabase(articleNo, rowData);
|
||||
for (const [articleNo, { newData }] of entries) {
|
||||
const success = await saveRowToSupabase(articleNo, newData);
|
||||
if (success) {
|
||||
setRowStatuses(prev => ({ ...prev, [articleNo]: 'saved' }));
|
||||
setPendingRows(prev => { const n = { ...prev }; delete n[articleNo]; return n; });
|
||||
@@ -343,7 +364,9 @@ export default function App() {
|
||||
undoMessage={undoHistory[0]?.message}
|
||||
undoSteps={undoHistory.length}
|
||||
pendingCount={Object.keys(pendingRows).length}
|
||||
pendingChanges={Object.fromEntries(Object.entries(pendingRows).map(([k, v]) => [k, { articleName: (v as any).articleName }]))}
|
||||
onSaveAll={handleSaveAll}
|
||||
onRevertRow={handleRevertRow}
|
||||
isSavingAll={isSavingAll}
|
||||
/>
|
||||
<div className="flex flex-1 overflow-hidden">
|
||||
|
||||
Reference in New Issue
Block a user