Hangover. WinForms. Restore deleted books

This commit is contained in:
Robert McRackan 2022-12-15 14:11:27 -05:00
parent 7ad0ab566a
commit b2cf837de7
8 changed files with 235 additions and 11 deletions

View File

@ -9,7 +9,6 @@ using Dinah.Core;
using DtoImporterService; using DtoImporterService;
using LibationFileManager; using LibationFileManager;
using Serilog; using Serilog;
using static System.Reflection.Metadata.BlobBuilder;
using static DtoImporterService.PerfLogger; using static DtoImporterService.PerfLogger;
namespace ApplicationServices namespace ApplicationServices
@ -336,7 +335,7 @@ namespace ApplicationServices
} }
#endregion #endregion
#region remove books #region remove/restore books
public static Task<int> RemoveBooksAsync(List<string> idsToRemove) => Task.Run(() => removeBooks(idsToRemove)); public static Task<int> RemoveBooksAsync(List<string> idsToRemove) => Task.Run(() => removeBooks(idsToRemove));
public static int RemoveBook(string idToRemove) => removeBooks(new() { idToRemove }); public static int RemoveBook(string idToRemove) => removeBooks(new() { idToRemove });
private static int removeBooks(List<string> idsToRemove) private static int removeBooks(List<string> idsToRemove)
@ -369,6 +368,35 @@ namespace ApplicationServices
throw; throw;
} }
} }
public static int RestoreBooks(this List<LibraryBook> libraryBooks)
{
try
{
if (libraryBooks is null || !libraryBooks.Any())
return 0;
using var context = DbContexts.GetContext();
// Attach() NoTracking entities before SaveChanges()
foreach (var lb in libraryBooks)
{
lb.IsDeleted = false;
context.Attach(lb).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
}
var qtyChanges = context.SaveChanges();
if (qtyChanges > 0)
finalizeLibrarySizeChange();
return qtyChanges;
}
catch (Exception ex)
{
Log.Logger.Error(ex, "Error restoring books");
throw;
}
}
#endregion #endregion
// call this whenever books are added or removed from library // call this whenever books are added or removed from library

View File

@ -39,6 +39,19 @@ namespace DataLayer
public static IQueryable<LibraryBook> GetLibrary(this IQueryable<LibraryBook> library) public static IQueryable<LibraryBook> GetLibrary(this IQueryable<LibraryBook> library)
=> library => library
.Where(lb => !lb.IsDeleted) .Where(lb => !lb.IsDeleted)
.getLibrary();
public static List<LibraryBook> GetDeletedLibraryBooks(this LibationContext context)
=> context
.LibraryBooks
.AsNoTrackingWithIdentityResolution()
.Where(lb => lb.IsDeleted)
.getLibrary()
.ToList();
/// <summary>This is still IQueryable. YOU MUST CALL ToList() YOURSELF</summary>
private static IQueryable<LibraryBook> getLibrary(this IQueryable<LibraryBook> library)
=> library
// owned items are always loaded. eg: book.UserDefinedItem, book.Supplements // owned items are always loaded. eg: book.UserDefinedItem, book.Supplements
.Include(le => le.Book).ThenInclude(b => b.SeriesLink).ThenInclude(sb => sb.Series) .Include(le => le.Book).ThenInclude(b => b.SeriesLink).ThenInclude(sb => sb.Series)
.Include(le => le.Book).ThenInclude(b => b.ContributorsLink).ThenInclude(c => c.Contributor) .Include(le => le.Book).ThenInclude(b => b.ContributorsLink).ThenInclude(c => c.Contributor)

View File

@ -1,3 +1,4 @@
using AppScaffolding;
using Avalonia.Controls; using Avalonia.Controls;
using HangoverAvalonia.ViewModels; using HangoverAvalonia.ViewModels;
@ -9,6 +10,10 @@ namespace HangoverAvalonia.Views
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
var config = LibationScaffolding.RunPreConfigMigrations();
LibationScaffolding.RunPostConfigMigrations(config);
LibationScaffolding.RunPostMigrationScaffolding(config);
} }
public void Execute_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) public void Execute_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)

View File

@ -11,7 +11,7 @@ namespace HangoverWinForms
private void cliTab_VisibleChanged(object sender, EventArgs e) private void cliTab_VisibleChanged(object sender, EventArgs e)
{ {
if (!databaseTab.Visible) if (!cliTab.Visible)
return; return;
} }
} }

View File

@ -0,0 +1,73 @@
using ApplicationServices;
using DataLayer;
namespace HangoverWinForms
{
public partial class Form1
{
private string deletedCheckedTemplate;
private void Load_deletedTab()
{
deletedCheckedTemplate = deletedCheckedLbl.Text;
}
private void deletedTab_VisibleChanged(object sender, EventArgs e)
{
if (!deletedTab.Visible)
return;
if (deletedCbl.Items.Count == 0)
reload();
}
private void deletedCbl_ItemCheck(object sender, ItemCheckEventArgs e)
{
// CheckedItems.Count is not updated until after the event fires
setLabel(e.NewValue);
}
private void checkAllBtn_Click(object sender, EventArgs e)
{
for (var i = 0; i < deletedCbl.Items.Count; i++)
deletedCbl.SetItemChecked(i, true);
}
private void uncheckAllBtn_Click(object sender, EventArgs e)
{
for (var i = 0; i < deletedCbl.Items.Count; i++)
deletedCbl.SetItemChecked(i, false);
}
private void saveBtn_Click(object sender, EventArgs e)
{
var libraryBooksToRestore = deletedCbl.CheckedItems.Cast<LibraryBook>().ToList();
var qtyChanges = libraryBooksToRestore.RestoreBooks();
if (qtyChanges > 0)
reload();
}
private void reload()
{
deletedCbl.Items.Clear();
var deletedBooks = DbContexts.GetContext().GetDeletedLibraryBooks();
foreach (var lb in deletedBooks)
deletedCbl.Items.Add(lb);
setLabel();
}
private void setLabel(CheckState? checkedState = null)
{
var pre = deletedCbl.CheckedItems.Count;
int count = checkedState switch
{
CheckState.Checked => pre + 1,
CheckState.Unchecked => pre - 1,
_ => pre,
};
deletedCheckedLbl.Text = string.Format(deletedCheckedTemplate, count, deletedCbl.Items.Count);
}
}
}

View File

@ -36,14 +36,23 @@
this.sqlTb = new System.Windows.Forms.TextBox(); this.sqlTb = new System.Windows.Forms.TextBox();
this.sqlLbl = new System.Windows.Forms.Label(); this.sqlLbl = new System.Windows.Forms.Label();
this.databaseFileLbl = new System.Windows.Forms.Label(); this.databaseFileLbl = new System.Windows.Forms.Label();
this.deletedTab = new System.Windows.Forms.TabPage();
this.deletedCheckedLbl = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.saveBtn = new System.Windows.Forms.Button();
this.uncheckAllBtn = new System.Windows.Forms.Button();
this.checkAllBtn = new System.Windows.Forms.Button();
this.deletedCbl = new System.Windows.Forms.CheckedListBox();
this.cliTab = new System.Windows.Forms.TabPage(); this.cliTab = new System.Windows.Forms.TabPage();
this.tabControl1.SuspendLayout(); this.tabControl1.SuspendLayout();
this.databaseTab.SuspendLayout(); this.databaseTab.SuspendLayout();
this.deletedTab.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
// //
// tabControl1 // tabControl1
// //
this.tabControl1.Controls.Add(this.databaseTab); this.tabControl1.Controls.Add(this.databaseTab);
this.tabControl1.Controls.Add(this.deletedTab);
this.tabControl1.Controls.Add(this.cliTab); this.tabControl1.Controls.Add(this.cliTab);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(0, 0); this.tabControl1.Location = new System.Drawing.Point(0, 0);
@ -119,6 +128,86 @@
this.databaseFileLbl.TabIndex = 0; this.databaseFileLbl.TabIndex = 0;
this.databaseFileLbl.Text = "Database file: "; this.databaseFileLbl.Text = "Database file: ";
// //
// deletedTab
//
this.deletedTab.Controls.Add(this.deletedCheckedLbl);
this.deletedTab.Controls.Add(this.label1);
this.deletedTab.Controls.Add(this.saveBtn);
this.deletedTab.Controls.Add(this.uncheckAllBtn);
this.deletedTab.Controls.Add(this.checkAllBtn);
this.deletedTab.Controls.Add(this.deletedCbl);
this.deletedTab.Location = new System.Drawing.Point(4, 24);
this.deletedTab.Name = "deletedTab";
this.deletedTab.Padding = new System.Windows.Forms.Padding(3);
this.deletedTab.Size = new System.Drawing.Size(792, 422);
this.deletedTab.TabIndex = 2;
this.deletedTab.Text = "Deleted Books";
this.deletedTab.UseVisualStyleBackColor = true;
//
// deletedCheckedLbl
//
this.deletedCheckedLbl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.deletedCheckedLbl.AutoSize = true;
this.deletedCheckedLbl.Location = new System.Drawing.Point(233, 395);
this.deletedCheckedLbl.Name = "deletedCheckedLbl";
this.deletedCheckedLbl.Size = new System.Drawing.Size(104, 15);
this.deletedCheckedLbl.TabIndex = 6;
this.deletedCheckedLbl.Text = "Checked: {0} of {1}";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(8, 3);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(239, 15);
this.label1.TabIndex = 0;
this.label1.Text = "To restore deleted book, check box and save";
//
// saveBtn
//
this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.saveBtn.Location = new System.Drawing.Point(709, 391);
this.saveBtn.Name = "saveBtn";
this.saveBtn.Size = new System.Drawing.Size(75, 23);
this.saveBtn.TabIndex = 5;
this.saveBtn.Text = "Save";
this.saveBtn.UseVisualStyleBackColor = true;
this.saveBtn.Click += new System.EventHandler(this.saveBtn_Click);
//
// uncheckAllBtn
//
this.uncheckAllBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.uncheckAllBtn.Location = new System.Drawing.Point(129, 391);
this.uncheckAllBtn.Name = "uncheckAllBtn";
this.uncheckAllBtn.Size = new System.Drawing.Size(98, 23);
this.uncheckAllBtn.TabIndex = 4;
this.uncheckAllBtn.Text = "Uncheck All";
this.uncheckAllBtn.UseVisualStyleBackColor = true;
this.uncheckAllBtn.Click += new System.EventHandler(this.uncheckAllBtn_Click);
//
// checkAllBtn
//
this.checkAllBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.checkAllBtn.Location = new System.Drawing.Point(8, 391);
this.checkAllBtn.Name = "checkAllBtn";
this.checkAllBtn.Size = new System.Drawing.Size(98, 23);
this.checkAllBtn.TabIndex = 3;
this.checkAllBtn.Text = "Check All";
this.checkAllBtn.UseVisualStyleBackColor = true;
this.checkAllBtn.Click += new System.EventHandler(this.checkAllBtn_Click);
//
// deletedCbl
//
this.deletedCbl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.deletedCbl.FormattingEnabled = true;
this.deletedCbl.Location = new System.Drawing.Point(8, 21);
this.deletedCbl.Name = "deletedCbl";
this.deletedCbl.Size = new System.Drawing.Size(776, 364);
this.deletedCbl.TabIndex = 2;
this.deletedCbl.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.deletedCbl_ItemCheck);
//
// cliTab // cliTab
// //
this.cliTab.Location = new System.Drawing.Point(4, 24); this.cliTab.Location = new System.Drawing.Point(4, 24);
@ -140,6 +229,8 @@
this.tabControl1.ResumeLayout(false); this.tabControl1.ResumeLayout(false);
this.databaseTab.ResumeLayout(false); this.databaseTab.ResumeLayout(false);
this.databaseTab.PerformLayout(); this.databaseTab.PerformLayout();
this.deletedTab.ResumeLayout(false);
this.deletedTab.PerformLayout();
this.ResumeLayout(false); this.ResumeLayout(false);
} }
@ -154,5 +245,12 @@
private Label sqlLbl; private Label sqlLbl;
private Button sqlExecuteBtn; private Button sqlExecuteBtn;
private TabPage cliTab; private TabPage cliTab;
private TabPage deletedTab;
private CheckedListBox deletedCbl;
private Label label1;
private Button saveBtn;
private Button uncheckAllBtn;
private Button checkAllBtn;
private Label deletedCheckedLbl;
} }
} }

View File

@ -1,4 +1,6 @@
namespace HangoverWinForms using AppScaffolding;
namespace HangoverWinForms
{ {
public partial class Form1 : Form public partial class Form1 : Form
{ {
@ -6,11 +8,17 @@
{ {
InitializeComponent(); InitializeComponent();
var config = LibationScaffolding.RunPreConfigMigrations();
LibationScaffolding.RunPostConfigMigrations(config);
LibationScaffolding.RunPostMigrationScaffolding(config);
databaseTab.VisibleChanged += databaseTab_VisibleChanged; databaseTab.VisibleChanged += databaseTab_VisibleChanged;
cliTab.VisibleChanged += cliTab_VisibleChanged; cliTab.VisibleChanged += cliTab_VisibleChanged;
deletedTab.VisibleChanged += deletedTab_VisibleChanged;
Load_databaseTab(); Load_databaseTab();
Load_cliTab(); Load_cliTab();
Load_deletedTab();
} }
} }
} }

View File

@ -383,7 +383,6 @@ namespace LibationWinForms.GridView
if (visibleCount != bindingList.Count) if (visibleCount != bindingList.Count)
VisibleCountChanged?.Invoke(this, bindingList.BookEntries().Count()); VisibleCountChanged?.Invoke(this, bindingList.BookEntries().Count());
} }
#endregion #endregion