From b8c90886ef1f3afb8d908aac89028bd177836cae Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Thu, 9 Jul 2026 16:09:35 -0400 Subject: feat(admin): multi-select with shift+drag for common bulk operations --- internal/admin/undo.go | 97 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 27 deletions(-) (limited to 'internal/admin/undo.go') diff --git a/internal/admin/undo.go b/internal/admin/undo.go index 4c39ec6..53af942 100644 --- a/internal/admin/undo.go +++ b/internal/admin/undo.go @@ -11,9 +11,12 @@ import ( ) type ExtraFile struct { - FilePath string `json:"file_path"` - OldContent []byte `json:"-"` - NewContent []byte `json:"-"` + FilePath string `json:"file_path"` + OldContent []byte `json:"-"` + NewContent []byte `json:"-"` + NewFilePath string `json:"new_file_path,omitempty"` + IsDelete bool `json:"is_delete,omitempty"` + IsCreate bool `json:"is_create,omitempty"` } type ChangeDesc struct { @@ -140,14 +143,12 @@ func (us *UndoStack) applyUndo(c ChangeDesc) error { } } for _, ef := range c.ExtraFiles { - os.MkdirAll(filepath.Dir(ef.FilePath), 0755) - os.WriteFile(ef.FilePath, ef.OldContent, 0644) + applyUndoExtraFile(ef) } } else if c.IsCreate { os.Remove(c.FilePath) for _, ef := range c.ExtraFiles { - os.MkdirAll(filepath.Dir(ef.FilePath), 0755) - os.WriteFile(ef.FilePath, ef.OldContent, 0644) + applyUndoExtraFile(ef) } } else { target := c.FilePath @@ -160,8 +161,7 @@ func (us *UndoStack) applyUndo(c ChangeDesc) error { return fmt.Errorf("revert %s: %w", target, err) } for _, ef := range c.ExtraFiles { - os.MkdirAll(filepath.Dir(ef.FilePath), 0755) - os.WriteFile(ef.FilePath, ef.OldContent, 0644) + applyUndoExtraFile(ef) } } return nil @@ -181,14 +181,12 @@ func (us *UndoStack) applyRedo(c ChangeDesc) error { return fmt.Errorf("recreate %s: %w", target, err) } for _, ef := range c.ExtraFiles { - os.MkdirAll(filepath.Dir(ef.FilePath), 0755) - os.WriteFile(ef.FilePath, ef.NewContent, 0644) + applyRedoExtraFile(ef) } } else if c.IsDelete { os.Remove(c.FilePath) for _, ef := range c.ExtraFiles { - os.MkdirAll(filepath.Dir(ef.FilePath), 0755) - os.WriteFile(ef.FilePath, ef.NewContent, 0644) + applyRedoExtraFile(ef) } } else { target := c.FilePath @@ -201,13 +199,46 @@ func (us *UndoStack) applyRedo(c ChangeDesc) error { return fmt.Errorf("reapply %s: %w", target, err) } for _, ef := range c.ExtraFiles { - os.MkdirAll(filepath.Dir(ef.FilePath), 0755) - os.WriteFile(ef.FilePath, ef.NewContent, 0644) + applyRedoExtraFile(ef) } } return nil } +func applyUndoExtraFile(ef ExtraFile) { + switch { + case ef.IsCreate: + os.Remove(ef.FilePath) + case ef.IsDelete: + os.MkdirAll(filepath.Dir(ef.FilePath), 0755) + os.WriteFile(ef.FilePath, ef.OldContent, 0644) + case ef.NewFilePath != "": + os.Remove(ef.NewFilePath) + os.MkdirAll(filepath.Dir(ef.FilePath), 0755) + os.WriteFile(ef.FilePath, ef.OldContent, 0644) + default: + os.MkdirAll(filepath.Dir(ef.FilePath), 0755) + os.WriteFile(ef.FilePath, ef.OldContent, 0644) + } +} + +func applyRedoExtraFile(ef ExtraFile) { + switch { + case ef.IsDelete: + os.Remove(ef.FilePath) + case ef.IsCreate: + os.MkdirAll(filepath.Dir(ef.FilePath), 0755) + os.WriteFile(ef.FilePath, ef.NewContent, 0644) + case ef.NewFilePath != "": + os.Remove(ef.FilePath) + os.MkdirAll(filepath.Dir(ef.NewFilePath), 0755) + os.WriteFile(ef.NewFilePath, ef.NewContent, 0644) + default: + os.MkdirAll(filepath.Dir(ef.FilePath), 0755) + os.WriteFile(ef.FilePath, ef.NewContent, 0644) + } +} + func (us *UndoStack) Info() UndoInfo { us.mu.Lock() defer us.mu.Unlock() @@ -228,9 +259,12 @@ func (us *UndoStack) Info() UndoInfo { func (us *UndoStack) save() { type extraEntry struct { - FilePath string `json:"file_path"` - OldContent string `json:"old_content"` - NewContent string `json:"new_content"` + FilePath string `json:"file_path"` + NewFilePath string `json:"new_file_path,omitempty"` + OldContent string `json:"old_content"` + NewContent string `json:"new_content"` + IsDelete bool `json:"is_delete,omitempty"` + IsCreate bool `json:"is_create,omitempty"` } type entry struct { Time string `json:"time"` @@ -253,9 +287,12 @@ func (us *UndoStack) save() { var extra []extraEntry for _, ef := range c.ExtraFiles { extra = append(extra, extraEntry{ - FilePath: ef.FilePath, - OldContent: string(ef.OldContent), - NewContent: string(ef.NewContent), + FilePath: ef.FilePath, + NewFilePath: ef.NewFilePath, + OldContent: string(ef.OldContent), + NewContent: string(ef.NewContent), + IsDelete: ef.IsDelete, + IsCreate: ef.IsCreate, }) } entries = append(entries, entry{ @@ -293,9 +330,12 @@ func (us *UndoStack) load() { } log.Printf("undo: loaded history from %s", us.filePath) type extraEntry struct { - FilePath string `json:"file_path"` - OldContent string `json:"old_content"` - NewContent string `json:"new_content"` + FilePath string `json:"file_path"` + NewFilePath string `json:"new_file_path,omitempty"` + OldContent string `json:"old_content"` + NewContent string `json:"new_content"` + IsDelete bool `json:"is_delete,omitempty"` + IsCreate bool `json:"is_create,omitempty"` } type entry struct { Time string `json:"time"` @@ -322,9 +362,12 @@ func (us *UndoStack) load() { var extra []ExtraFile for _, ef := range e.ExtraFiles { extra = append(extra, ExtraFile{ - FilePath: ef.FilePath, - OldContent: []byte(ef.OldContent), - NewContent: []byte(ef.NewContent), + FilePath: ef.FilePath, + NewFilePath: ef.NewFilePath, + OldContent: []byte(ef.OldContent), + NewContent: []byte(ef.NewContent), + IsDelete: ef.IsDelete, + IsCreate: ef.IsCreate, }) } changes = append(changes, ChangeDesc{ -- cgit v1.2.3