diff --git a/Resumer/cli/commands/delete/DeleteCommand.cs b/Resumer/cli/commands/delete/DeleteCommand.cs new file mode 100644 index 0000000..1f1411b --- /dev/null +++ b/Resumer/cli/commands/delete/DeleteCommand.cs @@ -0,0 +1,68 @@ +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using Microsoft.EntityFrameworkCore; +using Resumer.models; +using Spectre.Console; +using Spectre.Console.Cli; + +namespace Resumer.cli.commands.delete; + +public abstract class + DeleteCommand<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>: Command + where T : class +{ + private string TypeName { get; } = typeof(T).Name.ToLower(); + protected ResumeContext Db { get; set; } = new(); + protected abstract DbSet DbSet { get; } + + public sealed override int Execute(CommandContext context, DeleteCommandSettings settings) + { + if(!DbSet.Any()) + return CommandOutput.Error(ExitCode.Canceled, $"No {TypeName} found"); + + var confirmDelete = !settings.NoConfirm; + string prompt; + List selected; + + if(settings.DeleteAll) + { + prompt = $"Are you sure you want to delete all {DbSet.Count()} {TypeName}?"; + if(confirmDelete) + { + AnsiConsole.WriteLine(DbSet.Print()); + if(!AnsiConsole.Confirm(prompt, false)) + return CommandOutput.Error(ExitCode.Canceled); + } + + selected = DbSet.ToList(); + } + else + { + selected = AnsiConsole.Prompt( + new MultiSelectionPrompt() + .Title($"Select {TypeName}s to delete") + .PageSize(10).AddChoices(DbSet) + ); + prompt = selected.Count == 1 + ? $"Are you sure you want to delete this {TypeName} - {selected[0]}?" + : $"Are you sure you want to delete these {selected.Count} {TypeName}s?"; + if(confirmDelete && !AnsiConsole.Confirm(prompt, false)) + return CommandOutput.Error(ExitCode.Canceled); + } + + DbSet.RemoveRange(selected); + var deleted = Db.SaveChanges(); + return CommandOutput.Success(deleted == 1 ? "1 job deleted." : $"{deleted} jobs deleted."); + } +} + +public class DeleteCommandSettings: CommandSettings +{ + [CommandOption("-n|--no-confirm")] + [Description("Do not ask for confirmation before deleting")] + public bool NoConfirm { get; set; } + + [CommandOption("-a|--all")] + [Description("Delete all entries")] + public bool DeleteAll { get; set; } +} \ No newline at end of file diff --git a/Resumer/cli/commands/delete/DeleteCommandSettings.cs b/Resumer/cli/commands/delete/DeleteCommandSettings.cs deleted file mode 100644 index 574eab5..0000000 --- a/Resumer/cli/commands/delete/DeleteCommandSettings.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ComponentModel; -using Spectre.Console.Cli; - -namespace Resumer.cli.commands.delete; - -public class DeleteCommandSettings:CommandSettings -{ - [CommandOption("-n|--no-confirm")] - [Description("Do not ask for confirmation before deleting")] - public bool NoConfirm { get; set; } - - [CommandOption("-a|--all")] - [Description("Delete all entries")] - public bool DeleteAll { get; set; } - -} \ No newline at end of file diff --git a/Resumer/cli/commands/delete/DeleteJobCommand.cs b/Resumer/cli/commands/delete/DeleteJobCommand.cs index 0ac27fb..f53cf7c 100644 --- a/Resumer/cli/commands/delete/DeleteJobCommand.cs +++ b/Resumer/cli/commands/delete/DeleteJobCommand.cs @@ -1,41 +1,11 @@ +using Microsoft.EntityFrameworkCore; using Resumer.models; using Spectre.Console; using Spectre.Console.Cli; namespace Resumer.cli.commands.delete; -public class DeleteJobCommand: Command +public class DeleteJobCommand: DeleteCommand { - public override int Execute(CommandContext context, DeleteCommandSettings settings) - { - var db = new ResumeContext(); - var jobs = db.Jobs; - - if(!jobs.Any()) - return CommandOutput.Success("No jobs found."); - else if(settings.DeleteAll) - { - if(!settings.NoConfirm && !AnsiConsole.Confirm("Are you sure you want to delete all jobs?", false)) - return CommandOutput.Error(ExitCode.Canceled); - jobs.RemoveRange(jobs); - } - else - { - var selected = - AnsiConsole.Prompt(new MultiSelectionPrompt().Title("Select job(s) to delete").AddChoices(jobs)); - - AnsiConsole.WriteLine($"Deleting {selected.Count} jobs..."); - selected.ForEach(job => AnsiConsole.MarkupLine($"- {job}")); - - var prompt = selected.Count == 1 - ? $"Are you sure you want to delete {selected[0]}?" - : $"Are you sure you want to delete these {selected.Count} jobs?"; - if(!settings.NoConfirm && !AnsiConsole.Confirm(prompt)) - return CommandOutput.Error(ExitCode.Canceled); - jobs.RemoveRange(selected); - } - - var deleted = db.SaveChanges(); - return CommandOutput.Success(deleted == 1 ? "1 job deleted." : $"{deleted} jobs deleted."); - } + protected override DbSet DbSet => Db.Jobs; } \ No newline at end of file diff --git a/Resumer/cli/commands/delete/DeleteProfileCommand.cs b/Resumer/cli/commands/delete/DeleteProfileCommand.cs index 284294f..26cf0c3 100644 --- a/Resumer/cli/commands/delete/DeleteProfileCommand.cs +++ b/Resumer/cli/commands/delete/DeleteProfileCommand.cs @@ -1,3 +1,4 @@ +using Microsoft.EntityFrameworkCore; using Resumer.models; using Spectre.Console; using Spectre.Console.Cli; @@ -5,38 +6,8 @@ namespace Resumer.cli.commands.delete; -public class DeleteProfileCommand : Command +public class DeleteProfileCommand : DeleteCommand { - public override int Execute(CommandContext context, DeleteCommandSettings settings) - { - var db = new ResumeContext(); - var profiles = db.Profiles; - if(!profiles.Any()) - return CommandOutput.Success("No profiles found"); - else if(settings.DeleteAll) - { - if(!settings.NoConfirm && !AnsiConsole.Confirm("Are you sure you want to delete all profiles?")) - return CommandOutput.Error(ExitCode.Canceled); - profiles.RemoveRange(profiles); - } - else - { - var selected = AnsiConsole.Prompt(new MultiSelectionPrompt() - .Title("Select a profile to delete") - .AddChoices(profiles.AsEnumerable().OrderBy(p => p.ToString()).ToList())); + protected override DbSet DbSet => Db.Profiles; - AnsiConsole.WriteLine($"Deleting {selected.Count} profiles..."); - selected.ForEach(profile => AnsiConsole.MarkupLine($"- {profile}")); - - var prompt = selected.Count == 1 - ? $"Are you sure you want to delete {selected[0]}?" - : $"Are you sure you want to delete these {selected.Count} profiles?"; - if(!settings.NoConfirm && !AnsiConsole.Confirm(prompt,false)) - return CommandOutput.Error(ExitCode.Canceled); - profiles.RemoveRange(selected); - } - - var deleted = db.SaveChanges(); - return CommandOutput.Success(deleted == 1 ? "Profile deleted" : $"{deleted} profiles deleted"); - } } \ No newline at end of file diff --git a/Resumer/cli/commands/delete/DeleteProjectCommand.cs b/Resumer/cli/commands/delete/DeleteProjectCommand.cs index 53ab115..777511a 100644 --- a/Resumer/cli/commands/delete/DeleteProjectCommand.cs +++ b/Resumer/cli/commands/delete/DeleteProjectCommand.cs @@ -1,40 +1,12 @@ +using Microsoft.EntityFrameworkCore; using Resumer.models; using Spectre.Console; using Spectre.Console.Cli; namespace Resumer.cli.commands.delete; -public class DeleteProjectCommand: Command +public class DeleteProjectCommand: DeleteCommand { - public override int Execute(CommandContext context, DeleteCommandSettings settings) - { - var db = new ResumeContext(); - var projects = db.Projects; - if(!projects.Any()) - return CommandOutput.Success("No projects found"); - else if(settings.DeleteAll) - { - if(!settings.NoConfirm && !AnsiConsole.Confirm("Are you sure you want to delete all projects?")) - return CommandOutput.Error(ExitCode.Canceled); - projects.RemoveRange(projects); - var deleted = db.SaveChanges(); - return CommandOutput.Success(deleted == 1 ? "project deleted" : $"{deleted} projects deleted"); - } - else - { - var selectedProjects = AnsiConsole.Prompt(new MultiSelectionPrompt() - .Title("Select projects to delete") - .PageSize(10) - .AddChoices(projects)); + protected override DbSet DbSet => Db.Projects; - var prompt = selectedProjects.Count == 1 - ? $"Are you sure you want to delete this project - {selectedProjects[0].Title}?" - : $"Are you sure you want to delete these {selectedProjects.Count} projects?"; - if(!settings.NoConfirm && !AnsiConsole.Confirm(prompt, false)) - return CommandOutput.Error(ExitCode.Canceled); - projects.RemoveRange(selectedProjects); - var deleted = db.SaveChanges(); - return CommandOutput.Success(deleted == 1 ? "project deleted" : $"{deleted} projects deleted"); - } - } } \ No newline at end of file diff --git a/Resumer/cli/commands/delete/DeleteSkillCommand.cs b/Resumer/cli/commands/delete/DeleteSkillCommand.cs index b613064..6c2dbc3 100644 --- a/Resumer/cli/commands/delete/DeleteSkillCommand.cs +++ b/Resumer/cli/commands/delete/DeleteSkillCommand.cs @@ -1,36 +1,12 @@ +using Microsoft.EntityFrameworkCore; using Resumer.models; using Spectre.Console; using Spectre.Console.Cli; namespace Resumer.cli.commands.delete; -public class DeleteSkillCommand: Command +public class DeleteSkillCommand: DeleteCommand { - public override int Execute(CommandContext context, DeleteCommandSettings settings) - { - var db = new ResumeContext(); - var skills = db.Skills; - if(!skills.Any()) - return CommandOutput.Success("No skills found"); - else if(settings.DeleteAll) - { - if(!settings.NoConfirm && !AnsiConsole.Confirm($"Are you sure you want to delete all {skills.Count()} skills?", false)) - return CommandOutput.Error(ExitCode.Canceled); - skills.RemoveRange(skills); - } - else - { - var selected = AnsiConsole.Prompt(new MultiSelectionPrompt().Title("Select skills to delete") - .PageSize(10).AddChoices(skills)); - var prompt = selected.Count == 1 - ? $"Are you sure you want to delete this skill - {selected[0]}?" - : $"Are you sure you want to delete these {selected.Count} skills?"; - if(!settings.NoConfirm && !AnsiConsole.Confirm(prompt)) - return CommandOutput.Error(ExitCode.Canceled); - skills.RemoveRange(selected); - } + protected override DbSet DbSet => Db.Skills; - var deleted = db.SaveChanges(); - return CommandOutput.Success(deleted == 1 ? "Skill deleted" : $"{deleted} skills deleted"); - } } \ No newline at end of file diff --git a/Resumer/cli/commands/delete/DeleteTypstTemplateCommand.cs b/Resumer/cli/commands/delete/DeleteTypstTemplateCommand.cs index b9fe7b8..7679d6a 100644 --- a/Resumer/cli/commands/delete/DeleteTypstTemplateCommand.cs +++ b/Resumer/cli/commands/delete/DeleteTypstTemplateCommand.cs @@ -1,39 +1,11 @@ +using Microsoft.EntityFrameworkCore; using Resumer.models; using Spectre.Console; using Spectre.Console.Cli; namespace Resumer.cli.commands.delete; -public class DeleteTypstTemplateCommand: Command +public class DeleteTypstTemplateCommand: DeleteCommand { - public override int Execute(CommandContext context, DeleteCommandSettings settings) - { - var db = new ResumeContext(); - var typstTemplates = db.Templates; - if(!typstTemplates.Any()) - return CommandOutput.Success("No templates found"); - else if(settings.DeleteAll) - { - if(!settings.NoConfirm && !AnsiConsole.Confirm("Are you sure you want to delete all templates?", false)) - return CommandOutput.Error(ExitCode.Canceled); - typstTemplates.RemoveRange(typstTemplates); - } - else - { - var selectedTypstTemplates = AnsiConsole.Prompt(new MultiSelectionPrompt() - .Title("Select templates to delete") - .PageSize(10) - .AddChoices(typstTemplates.OrderBy(template => template.Name))); - - var prompt = selectedTypstTemplates.Count == 1 - ? $"Are you sure you want to delete this typst template - {selectedTypstTemplates[0].Name}?" - : $"Are you sure you want to delete these {selectedTypstTemplates.Count} templates?"; - if(!settings.NoConfirm && !AnsiConsole.Confirm(prompt, false)) - return CommandOutput.Error(ExitCode.Canceled); - typstTemplates.RemoveRange(selectedTypstTemplates); - } - - var deleted = db.SaveChanges(); - return CommandOutput.Success(deleted == 1 ? "template deleted" : $"{deleted} typst templates deleted"); - } + protected override DbSet DbSet => Db.Templates; } \ No newline at end of file