From 7cf5058f9b1eeb445dbedd64c35f83a7b7a49076 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Fri, 29 May 2020 02:13:46 +0100 Subject: [PATCH] Allow to add and remove GPUs from machine details in admin view. --- .../Controllers/GpusByMachineController.cs | 163 ------------------ .../Admin/Views/GpusByMachine/Create.cshtml | 27 --- .../Admin/Views/GpusByMachine/Delete.cshtml | 30 ---- .../Admin/Views/GpusByMachine/Details.cshtml | 28 --- .../Admin/Views/GpusByMachine/Edit.cshtml | 30 ---- .../Admin/Views/GpusByMachine/Index.cshtml | 48 ------ Marechai/Marechai.csproj | 7 +- Marechai/Pages/Admin/Details/Machine.razor | 77 ++++++++- Marechai/Pages/Admin/Details/Machine.razor.cs | 132 ++++++++++++-- Marechai/Services/GpuByMachineService.cs | 48 ++++++ Marechai/Services/Register.cs | 1 + Marechai/ViewModels/GpuByMachineViewModel.cs | 10 ++ 12 files changed, 262 insertions(+), 339 deletions(-) delete mode 100644 Marechai/Areas/Admin/Controllers/GpusByMachineController.cs delete mode 100644 Marechai/Areas/Admin/Views/GpusByMachine/Create.cshtml delete mode 100644 Marechai/Areas/Admin/Views/GpusByMachine/Delete.cshtml delete mode 100644 Marechai/Areas/Admin/Views/GpusByMachine/Details.cshtml delete mode 100644 Marechai/Areas/Admin/Views/GpusByMachine/Edit.cshtml delete mode 100644 Marechai/Areas/Admin/Views/GpusByMachine/Index.cshtml create mode 100644 Marechai/Services/GpuByMachineService.cs create mode 100644 Marechai/ViewModels/GpuByMachineViewModel.cs diff --git a/Marechai/Areas/Admin/Controllers/GpusByMachineController.cs b/Marechai/Areas/Admin/Controllers/GpusByMachineController.cs deleted file mode 100644 index dc72640e..00000000 --- a/Marechai/Areas/Admin/Controllers/GpusByMachineController.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Marechai.Areas.Admin.Models; -using Marechai.Database.Models; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Rendering; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Query; - -namespace Marechai.Areas.Admin.Controllers -{ - [Area("Admin"), Authorize] - public class GpusByMachineController : Controller - { - readonly MarechaiContext _context; - - public GpusByMachineController(MarechaiContext context) => _context = context; - - // GET: GpusByMachine - public async Task Index() - { - IIncludableQueryable marechaiContext = - _context.GpusByMachine.Include(g => g.Gpu).Include(g => g.Machine); - - return View(await marechaiContext.OrderBy(g => g.Machine.Name).ThenBy(g => g.Gpu.Name). - Select(g => new GpusByMachineViewModel - { - Id = g.Id, Gpu = g.Gpu.Name, Machine = g.Machine.Name - }).ToListAsync()); - } - - // GET: GpusByMachine/Details/5 - public async Task Details(long? id) - { - if(id == null) - return NotFound(); - - GpusByMachine gpusByMachine = await _context. - GpusByMachine.Include(g => g.Gpu).Include(g => g.Machine). - FirstOrDefaultAsync(m => m.Id == id); - - if(gpusByMachine == null) - return NotFound(); - - return View(gpusByMachine); - } - - // GET: GpusByMachine/Create - public IActionResult Create() - { - ViewData["GpuId"] = new SelectList(_context.Gpus.OrderBy(g => g.Name), "Id", "Name"); - ViewData["MachineId"] = new SelectList(_context.Machines.OrderBy(m => m.Name), "Id", "Name"); - - return View(); - } - - // POST: GpusByMachine/Create - // To protect from overposting attacks, please enable the specific properties you want to bind to, for - // more details see http://go.microsoft.com/fwlink/?LinkId=317598. - [HttpPost, ValidateAntiForgeryToken] - public async Task Create([Bind("GpuId,MachineId,Id")] GpusByMachine gpusByMachine) - { - if(ModelState.IsValid) - { - _context.Add(gpusByMachine); - await _context.SaveChangesAsync(); - - return RedirectToAction(nameof(Index)); - } - - ViewData["GpuId"] = new SelectList(_context.Gpus.OrderBy(g => g.Name), "Id", "Name", gpusByMachine.GpuId); - - ViewData["MachineId"] = - new SelectList(_context.Machines.OrderBy(m => m.Name), "Id", "Name", gpusByMachine.MachineId); - - return View(gpusByMachine); - } - - // GET: GpusByMachine/Edit/5 - public async Task Edit(long? id) - { - if(id == null) - return NotFound(); - - GpusByMachine gpusByMachine = await _context.GpusByMachine.FindAsync(id); - - if(gpusByMachine == null) - return NotFound(); - - ViewData["GpuId"] = new SelectList(_context.Gpus.OrderBy(g => g.Name), "Id", "Name", gpusByMachine.GpuId); - - ViewData["MachineId"] = - new SelectList(_context.Machines.OrderBy(m => m.Name), "Id", "Name", gpusByMachine.MachineId); - - return View(gpusByMachine); - } - - // POST: GpusByMachine/Edit/5 - // To protect from overposting attacks, please enable the specific properties you want to bind to, for - // more details see http://go.microsoft.com/fwlink/?LinkId=317598. - [HttpPost, ValidateAntiForgeryToken] - public async Task Edit(long id, [Bind("GpuId,MachineId,Id")] GpusByMachine gpusByMachine) - { - if(id != gpusByMachine.Id) - return NotFound(); - - if(ModelState.IsValid) - { - try - { - _context.Update(gpusByMachine); - await _context.SaveChangesAsync(); - } - catch(DbUpdateConcurrencyException) - { - if(!GpusByMachineExists(gpusByMachine.Id)) - return NotFound(); - - throw; - } - - return RedirectToAction(nameof(Index)); - } - - ViewData["GpuId"] = new SelectList(_context.Gpus.OrderBy(g => g.Name), "Id", "Name", gpusByMachine.GpuId); - - ViewData["MachineId"] = - new SelectList(_context.Machines.OrderBy(m => m.Name), "Id", "Name", gpusByMachine.MachineId); - - return View(gpusByMachine); - } - - // GET: GpusByMachine/Delete/5 - public async Task Delete(long? id) - { - if(id == null) - return NotFound(); - - GpusByMachine gpusByMachine = await _context. - GpusByMachine.Include(g => g.Gpu).Include(g => g.Machine). - FirstOrDefaultAsync(m => m.Id == id); - - if(gpusByMachine == null) - return NotFound(); - - return View(gpusByMachine); - } - - // POST: GpusByMachine/Delete/5 - [HttpPost, ActionName("Delete"), ValidateAntiForgeryToken] - public async Task DeleteConfirmed(long id) - { - GpusByMachine gpusByMachine = await _context.GpusByMachine.FindAsync(id); - _context.GpusByMachine.Remove(gpusByMachine); - await _context.SaveChangesAsync(); - - return RedirectToAction(nameof(Index)); - } - - bool GpusByMachineExists(long id) => _context.GpusByMachine.Any(e => e.Id == id); - } -} \ No newline at end of file diff --git a/Marechai/Areas/Admin/Views/GpusByMachine/Create.cshtml b/Marechai/Areas/Admin/Views/GpusByMachine/Create.cshtml deleted file mode 100644 index 7a919671..00000000 --- a/Marechai/Areas/Admin/Views/GpusByMachine/Create.cshtml +++ /dev/null @@ -1,27 +0,0 @@ -@model Marechai.Database.Models.GpusByMachine - -@{ - ViewData["Title"] = "Create"; -} -

Create

-

GPU by machine

-
-
-
-
-
-
- - -
-
- - -
-
- - Back to List -
-
-
-
\ No newline at end of file diff --git a/Marechai/Areas/Admin/Views/GpusByMachine/Delete.cshtml b/Marechai/Areas/Admin/Views/GpusByMachine/Delete.cshtml deleted file mode 100644 index d5ba289b..00000000 --- a/Marechai/Areas/Admin/Views/GpusByMachine/Delete.cshtml +++ /dev/null @@ -1,30 +0,0 @@ -@model Marechai.Database.Models.GpusByMachine - -@{ - ViewData["Title"] = "Delete"; -} -

Delete

-

Are you sure you want to delete this?

-
-

GPU by machine

-
-
-
- @Html.DisplayNameFor(model => model.Machine) -
-
- @Html.DisplayFor(model => model.Machine.Name) -
-
- @Html.DisplayNameFor(model => model.Gpu) -
-
- @Html.DisplayFor(model => model.Gpu.Name) -
-
-
- - - Back to List -
-
\ No newline at end of file diff --git a/Marechai/Areas/Admin/Views/GpusByMachine/Details.cshtml b/Marechai/Areas/Admin/Views/GpusByMachine/Details.cshtml deleted file mode 100644 index 86a02870..00000000 --- a/Marechai/Areas/Admin/Views/GpusByMachine/Details.cshtml +++ /dev/null @@ -1,28 +0,0 @@ -@model Marechai.Database.Models.GpusByMachine - -@{ - ViewData["Title"] = "Details"; -} -

Details

-
-

GPU by machine

-
-
-
- @Html.DisplayNameFor(model => model.Machine) -
-
- @Html.DisplayFor(model => model.Machine.Name) -
-
- @Html.DisplayNameFor(model => model.Gpu) -
-
- @Html.DisplayFor(model => model.Gpu.Name) -
-
-
- \ No newline at end of file diff --git a/Marechai/Areas/Admin/Views/GpusByMachine/Edit.cshtml b/Marechai/Areas/Admin/Views/GpusByMachine/Edit.cshtml deleted file mode 100644 index ea061b3f..00000000 --- a/Marechai/Areas/Admin/Views/GpusByMachine/Edit.cshtml +++ /dev/null @@ -1,30 +0,0 @@ -@model Marechai.Database.Models.GpusByMachine - -@{ - ViewData["Title"] = "Edit"; -} -

Edit

-

GpusByMachine

-
-
-
-
-
-
- - - -
-
- - - -
- -
- - Back to List -
-
-
-
\ No newline at end of file diff --git a/Marechai/Areas/Admin/Views/GpusByMachine/Index.cshtml b/Marechai/Areas/Admin/Views/GpusByMachine/Index.cshtml deleted file mode 100644 index 04c71476..00000000 --- a/Marechai/Areas/Admin/Views/GpusByMachine/Index.cshtml +++ /dev/null @@ -1,48 +0,0 @@ -@model IEnumerable - -@{ - ViewData["Title"] = "Index"; -} -

GPUs by machine

-

- - Create new - -

- - - - - - - - - - @foreach (var item in Model) - { - - - - - - } - -
- @Html.DisplayNameFor(model => model.Machine) - - @Html.DisplayNameFor(model => model.Gpu) -
- @Html.DisplayFor(modelItem => item.Machine) - - @Html.DisplayFor(modelItem => item.Gpu) - - - Details - - - Edit - - - Delete - -
\ No newline at end of file diff --git a/Marechai/Marechai.csproj b/Marechai/Marechai.csproj index 5c1e8e2c..1ba68db0 100644 --- a/Marechai/Marechai.csproj +++ b/Marechai/Marechai.csproj @@ -2,7 +2,7 @@ netcoreapp3.1 - 3.0.99.1364 + 3.0.99.1373 Canary Islands Computer Museum Copyright © 2003-2020 Natalia Portillo Canary Islands Computer Museum Website @@ -144,5 +144,10 @@ <_ContentIncludedByDefault Remove="Areas\Admin\Views\Screens\Create.cshtml" /> <_ContentIncludedByDefault Remove="Areas\Admin\Views\SoundSynths\Create.cshtml" /> <_ContentIncludedByDefault Remove="Areas\Admin\Views\CompanyLogos\Create.cshtml" /> + <_ContentIncludedByDefault Remove="Areas\Admin\Views\GpusByMachine\Create.cshtml" /> + <_ContentIncludedByDefault Remove="Areas\Admin\Views\GpusByMachine\Delete.cshtml" /> + <_ContentIncludedByDefault Remove="Areas\Admin\Views\GpusByMachine\Details.cshtml" /> + <_ContentIncludedByDefault Remove="Areas\Admin\Views\GpusByMachine\Edit.cshtml" /> + <_ContentIncludedByDefault Remove="Areas\Admin\Views\GpusByMachine\Index.cshtml" /> \ No newline at end of file diff --git a/Marechai/Pages/Admin/Details/Machine.razor b/Marechai/Pages/Admin/Details/Machine.razor index 0114e8c0..04c01d63 100644 --- a/Marechai/Pages/Admin/Details/Machine.razor +++ b/Marechai/Pages/Admin/Details/Machine.razor @@ -39,6 +39,8 @@ @inject CompaniesService CompaniesService @inject MachineFamiliesService MachineFamiliesService @inject NavigationManager NavigationManager +@inject GpuByMachineService GpuByMachineService +@inject GpusService GpusService @attribute [Authorize(Roles = "UberAdmin, Admin")]

@L["Machine details"]


@@ -154,4 +156,77 @@ } @L["Back to list"] - \ No newline at end of file + +@if (!_editing) +{ +
+

@L["Graphical processing units belonging to this machine"]

+ + @if (_addingGpu) + { +
+ + @L["Graphical processing units"] + + + + +
+ } + @if (_machineGpus?.Count > 0) + { +
+ + + + + + + + + + @foreach (var item in _machineGpus) + { + + + + + + } + +
+ @L["Company"] + + @L["Name"] +
+ @item.CompanyName + + @item.Name + + +
+
+ } + + + + + + @_deleteTitle + + + + @_deleteText + + + + + + + +} \ No newline at end of file diff --git a/Marechai/Pages/Admin/Details/Machine.razor.cs b/Marechai/Pages/Admin/Details/Machine.razor.cs index fcd5f89e..28e0e008 100644 --- a/Marechai/Pages/Admin/Details/Machine.razor.cs +++ b/Marechai/Pages/Admin/Details/Machine.razor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Blazorise; using Marechai.Database; @@ -11,16 +12,30 @@ namespace Marechai.Pages.Admin.Details { public partial class Machine { - List _companies; - bool _creating; + bool _addingGpu; + int? _addingGpuId; + List _companies; + bool _creating; + GpuByMachineViewModel _currentGpuByMachine; + + bool _deleteInProgress; + string _deleteText; + string _deleteTitle; + bool _deletingGpuByMachine; bool _editing; List _families; - bool _loaded; - MachineViewModel _model; - bool _noFamily; - bool _prototype; - bool _unknownIntroduced; - bool _unknownModel; + Modal _frmDelete; + + List _gpus; + bool _loaded; + List _machineGpus; + MachineViewModel _model; + bool _noFamily; + bool _prototype; + + bool _savingGpu; + bool _unknownIntroduced; + bool _unknownModel; [Parameter] public int Id { get; set; } @@ -44,9 +59,11 @@ namespace Marechai.Pages.Admin.Details !_creating) return; - _companies = await CompaniesService.GetAsync(); - _families = await MachineFamiliesService.GetAsync(); - _model = _creating ? new MachineViewModel() : await Service.GetAsync(Id); + _companies = await CompaniesService.GetAsync(); + _families = await MachineFamiliesService.GetAsync(); + _model = _creating ? new MachineViewModel() : await Service.GetAsync(Id); + _machineGpus = await GpuByMachineService.GetByMachine(Id); + _gpus = await GpusService.GetAsync(); _editing = _creating || NavigationManager.ToBaseRelativePath(NavigationManager.Uri).ToLowerInvariant(). StartsWith("admin/machines/edit/", @@ -127,5 +144,98 @@ namespace Marechai.Pages.Admin.Details Validators.ValidateString(e, L["Model must contain less than 50 characters."], 50); void ValidateIntroduced(ValidatorEventArgs e) => Validators.ValidateIntroducedDate(e); + + void ShowGpuDeleteModal(long itemId) + { + _currentGpuByMachine = _machineGpus.FirstOrDefault(n => n.Id == itemId); + _deletingGpuByMachine = true; + _deleteTitle = L["Delete graphical processing unit from this machine"]; + + _deleteText = + string.Format(L["Are you sure you want to delete the graphical processing unit {0} manufactured by {1} from this machine?"], + _currentGpuByMachine?.Name, _currentGpuByMachine?.CompanyName); + + _frmDelete.Show(); + } + + void HideModal() => _frmDelete.Hide(); + + async void ConfirmDelete() + { + if(_deletingGpuByMachine) + await ConfirmDeleteGpuByMachine(); + } + + async Task ConfirmDeleteGpuByMachine() + { + if(_currentGpuByMachine is null) + return; + + _deleteInProgress = true; + + // Yield thread to let UI to update + await Task.Yield(); + + await GpuByMachineService.DeleteAsync(_currentGpuByMachine.Id); + _machineGpus = await GpuByMachineService.GetByMachine(Id); + + _deleteInProgress = false; + _frmDelete.Hide(); + + // Yield thread to let UI to update + await Task.Yield(); + + // Tell we finished loading + StateHasChanged(); + } + + void ModalClosing(ModalClosingEventArgs obj) + { + _deleteInProgress = false; + _deletingGpuByMachine = false; + _currentGpuByMachine = null; + } + + async Task OnAddGpuClick() + { + _addingGpu = true; + _savingGpu = false; + _addingGpuId = null; + } + + void CancelAddGpu() + { + _addingGpu = false; + _savingGpu = false; + _addingGpuId = null; + } + + async Task ConfirmAddGpu() + { + if(_addingGpuId is null) + { + CancelAddGpu(); + + return; + } + + _savingGpu = true; + + // Yield thread to let UI to update + await Task.Yield(); + + await GpuByMachineService.CreateAsync(_addingGpuId.Value, Id); + _machineGpus = await GpuByMachineService.GetByMachine(Id); + + _addingGpu = false; + _savingGpu = false; + _addingGpuId = null; + + // Yield thread to let UI to update + await Task.Yield(); + + // Tell we finished loading + StateHasChanged(); + } } } \ No newline at end of file diff --git a/Marechai/Services/GpuByMachineService.cs b/Marechai/Services/GpuByMachineService.cs new file mode 100644 index 00000000..93a6b923 --- /dev/null +++ b/Marechai/Services/GpuByMachineService.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Marechai.Database.Models; +using Marechai.ViewModels; +using Microsoft.EntityFrameworkCore; + +namespace Marechai.Services +{ + public class GpuByMachineService + { + readonly MarechaiContext _context; + + public GpuByMachineService(MarechaiContext context) => _context = context; + + public async Task> GetByMachine(int machineId) => + await _context.GpusByMachine.Where(g => g.MachineId == machineId).Select(g => new GpuByMachineViewModel + { + Id = g.Id, Name = g.Gpu.Name, CompanyName = g.Gpu.Company.Name, GpuId = g.GpuId, + MachineId = g.MachineId + }).OrderBy(g => g.CompanyName).ThenBy(g => g.Name).ToListAsync(); + + public async Task DeleteAsync(long id) + { + GpusByMachine item = await _context.GpusByMachine.FindAsync(id); + + if(item is null) + return; + + _context.GpusByMachine.Remove(item); + + await _context.SaveChangesAsync(); + } + + public async Task CreateAsync(int gpuId, int machineId) + { + var item = new GpusByMachine + { + GpuId = gpuId, MachineId = machineId + }; + + await _context.GpusByMachine.AddAsync(item); + await _context.SaveChangesAsync(); + + return item.Id; + } + } +} \ No newline at end of file diff --git a/Marechai/Services/Register.cs b/Marechai/Services/Register.cs index e30f34eb..a99635e5 100644 --- a/Marechai/Services/Register.cs +++ b/Marechai/Services/Register.cs @@ -62,6 +62,7 @@ namespace Marechai.Services services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); } } } \ No newline at end of file diff --git a/Marechai/ViewModels/GpuByMachineViewModel.cs b/Marechai/ViewModels/GpuByMachineViewModel.cs new file mode 100644 index 00000000..f04dfb61 --- /dev/null +++ b/Marechai/ViewModels/GpuByMachineViewModel.cs @@ -0,0 +1,10 @@ +namespace Marechai.ViewModels +{ + public class GpuByMachineViewModel : BaseViewModel + { + public int GpuId { get; set; } + public int MachineId { get; set; } + public string CompanyName { get; set; } + public string Name { get; set; } + } +} \ No newline at end of file