Skip to content

Commit

Permalink
Added maintainer maintenance UI
Browse files Browse the repository at this point in the history
  • Loading branch information
davewalker5 committed Mar 12, 2024
1 parent 1c6f3a1 commit 3b01a3f
Show file tree
Hide file tree
Showing 18 changed files with 409 additions and 13 deletions.
4 changes: 2 additions & 2 deletions docker/api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM mcr.microsoft.com/dotnet/core/aspnet:latest
COPY droneflightlog.api-1.2.1.0 /opt/droneflightlog.api-1.2.1.0
WORKDIR /opt/droneflightlog.api-1.2.1.0/bin
COPY droneflightlog.api-1.2.2.0 /opt/droneflightlog.api-1.2.2.0
WORKDIR /opt/droneflightlog.api-1.2.2.0/bin
ENTRYPOINT [ "./DroneFlightLog.Api" ]
6 changes: 3 additions & 3 deletions src/DroneFlightLog.Api/DroneFlightLog.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ReleaseVersion>1.2.1.0</ReleaseVersion>
<FileVersion>1.2.1.0</FileVersion>
<ProductVersion>1.2.1.0</ProductVersion>
<ReleaseVersion>1.2.2.0</ReleaseVersion>
<FileVersion>1.2.2.0</FileVersion>
<ProductVersion>1.2.2.0</ProductVersion>
<Configurations>Release;Debug</Configurations>
<IsPackable>false</IsPackable>
</PropertyGroup>
Expand Down
100 changes: 100 additions & 0 deletions src/DroneFlightLog.Mvc/Api/MaintainersClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using DroneFlightLog.Mvc.Configuration;
using DroneFlightLog.Mvc.Entities;
using DroneFlightLog.Mvc.Interfaces;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace DroneFlightLog.Mvc.Api
{
public class MaintainersClient : DroneFlightLogClientBase
{
private const string RouteKey = "Maintainers";
private const string CacheKey = "Maintainers";

public MaintainersClient(HttpClient client, IOptions<AppSettings> settings, IHttpContextAccessor accessor, ICacheWrapper cache)
: base(client, settings, accessor, cache)
{
}

/// <summary>
/// Return a list of maintainer details
/// </summary>
/// <returns></returns>
public async Task<List<Maintainer>> GetMaintainersAsync()
{
List<Maintainer> maintainers = _cache.Get<List<Maintainer>>(CacheKey);
if (maintainers == null)
{
string json = await SendIndirectAsync(RouteKey, null, HttpMethod.Get);
maintainers = JsonConvert.DeserializeObject<List<Maintainer>>(json);
_cache.Set(CacheKey, maintainers, _settings.Value.CacheLifetimeSeconds);
}
return maintainers;
}

/// <summary>
/// Return the maintainer with the specified Id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<Maintainer> GetMaintainerAsync(int id)
{
List<Maintainer> maintainers = await GetMaintainersAsync();
Maintainer maintainer = maintainers.First(l => l.Id == id);
return maintainer;
}

/// <summary>
/// Create a new maintainer
/// </summary>
/// <param name="firstNames"></param>
/// <param name="surname"></param>
/// <returns></returns>
public async Task<Maintainer> AddMaintainerAsync(string firstNames, string surname)
{
_cache.Remove(CacheKey);

dynamic template = new
{
FirstNames = firstNames,
Surname = surname
};

string data = JsonConvert.SerializeObject(template);
string json = await SendIndirectAsync(RouteKey, data, HttpMethod.Post);

Maintainer maintainer = JsonConvert.DeserializeObject<Maintainer>(json);
return maintainer;
}

/// <summary>
/// Update an existing maintainer
/// </summary>
/// <param name="id"></param>
/// <param name="firstNames"></param>
/// <param name="surname"></param>
/// <returns></returns>
public async Task<Maintainer> UpdateMaintainerAsync(int id, string firstNames, string surname)
{
_cache.Remove(CacheKey);

dynamic template = new
{
Id = id,
FirstNames = firstNames,
Surname = surname
};

string data = JsonConvert.SerializeObject(template);
string json = await SendIndirectAsync(RouteKey, data, HttpMethod.Put);

Maintainer maintainer = JsonConvert.DeserializeObject<Maintainer>(json);
return maintainer;
}
}
}
2 changes: 0 additions & 2 deletions src/DroneFlightLog.Mvc/Api/OperatorClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ public async Task<List<Operator>> GetOperatorsAsync()
/// <returns></returns>
public async Task<Operator> GetOperatorAsync(int id)
{
// TODO : This needs to be replaced with a call to retrieve a single
// operator by Id. For now, retrieve them all then pick the one required
List<Operator> operators = await GetOperatorsAsync();
Operator op = operators.First(l => l.Id == id);
return op;
Expand Down
107 changes: 107 additions & 0 deletions src/DroneFlightLog.Mvc/Controllers/MaintainersController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using DroneFlightLog.Mvc.Api;
using DroneFlightLog.Mvc.Entities;
using DroneFlightLog.Mvc.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace DroneFlightLog.Mvc.Controllers
{
[Authorize]
public class MaintainersController : Controller
{
private readonly MaintainersClient _operators;

public MaintainersController(MaintainersClient maintainers)
{
_operators = maintainers;
}

/// <summary>
/// Serve the maintainers list page
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<IActionResult> Index()
{
List<Maintainer> operators = await _operators.GetMaintainersAsync();
return View(operators);
}

/// <summary>
/// Serve the page to add a new maintainer
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult Add()
{
return View(new AddMaintainerViewModel());
}

/// <summary>
/// Handle POST events to save new maintainers
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Add(AddMaintainerViewModel model)
{
if (ModelState.IsValid)
{
Maintainer maintainer = await _operators.AddMaintainerAsync(
model.Maintainer.FirstNames,
model.Maintainer.Surname);

ModelState.Clear();
model.Clear();
model.Message = $"Maintainer '{maintainer.FirstNames} {maintainer.Surname}' added successfully";
}

return View(model);
}

/// <summary>
/// Serve the page to edit an existing maintainer
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public async Task<IActionResult> Edit(int id)
{
Maintainer maintainer = await _operators.GetMaintainerAsync(id);
EditMaintainerViewModel model = new EditMaintainerViewModel();
model.Maintainer = maintainer;
return View(model);
}

/// <summary>
/// Handle POST events to update existing maintainers
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(EditMaintainerViewModel model)
{
IActionResult result;

if (ModelState.IsValid)
{
Maintainer maintainer = await _operators.UpdateMaintainerAsync(
model.Maintainer.Id,
model.Maintainer.FirstNames,
model.Maintainer.Surname);

result = RedirectToAction("Index");
}
else
{
result = View(model);
}

return result;
}
}
}
2 changes: 0 additions & 2 deletions src/DroneFlightLog.Mvc/DroneFlightLog.Mvc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@

<ItemGroup>
<Folder Include="Configuration\" />
<Folder Include="Api\" />
<Folder Include="Views\Login\" />
<Folder Include="Entities\" />
<Folder Include="Views\Manufacturers\" />
<Folder Include="Views\Models\" />
<Folder Include="Views\Drones\" />
Expand Down
18 changes: 18 additions & 0 deletions src/DroneFlightLog.Mvc/Entities/Maintainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace DroneFlightLog.Mvc.Entities
{
public class Maintainer
{
public int Id { get; set; }

[DisplayName("First Names")]
[Required(ErrorMessage = "You must provide a first name")]
public string FirstNames { get; set; }

[DisplayName("Surname")]
[Required(ErrorMessage = "You must provide a surname")]
public string Surname { get; set; }
}
}
6 changes: 6 additions & 0 deletions src/DroneFlightLog.Mvc/Models/AddMaintainerViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace DroneFlightLog.Mvc.Models
{
public class AddMaintainerViewModel : MaintainerViewModelBase
{
}
}
6 changes: 6 additions & 0 deletions src/DroneFlightLog.Mvc/Models/EditMaintainerViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace DroneFlightLog.Mvc.Models
{
public class EditMaintainerViewModel : MaintainerViewModelBase
{
}
}
21 changes: 21 additions & 0 deletions src/DroneFlightLog.Mvc/Models/MaintainerViewModelBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using DroneFlightLog.Mvc.Entities;

namespace DroneFlightLog.Mvc.Models
{
public abstract class MaintainerViewModelBase
{
public Maintainer Maintainer { get; set; }
public string Message { get; set; }

public MaintainerViewModelBase()
{
Clear();
}

public virtual void Clear()
{
Maintainer = new Maintainer();
Message = "";
}
}
}
1 change: 1 addition & 0 deletions src/DroneFlightLog.Mvc/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public void ConfigureServices(IServiceCollection services)
services.AddHttpClient<FlightPropertyClient>();
services.AddHttpClient<FlightSearchClient>();
services.AddHttpClient<FlightClient>();
services.AddHttpClient<MaintainersClient>();

// Configure session state for token storage
services.AddSession(options =>
Expand Down
30 changes: 30 additions & 0 deletions src/DroneFlightLog.Mvc/Views/Maintainers/Add.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@model DroneFlightLog.Mvc.Models.AddMaintainerViewModel

@{
ViewData["Title"] = "Add Maintainer";
}

<div class="container-fluid">
@using (Html.BeginForm())
{
<div class="row">
<div class="col-md">
<span style="font-size: 1.2rem"><strong>Add Maintainer</strong></span>
</div>
</div>
<hr />

@if (!string.IsNullOrEmpty(Model.Message))
{
<div class="row">
<div class="col-md">
<span>@Html.Raw(Model.Message)</span>
</div>
</div>
<br />
}

@await Html.PartialAsync("Maintainer", Model)
;
}
</div>
20 changes: 20 additions & 0 deletions src/DroneFlightLog.Mvc/Views/Maintainers/Edit.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@model DroneFlightLog.Mvc.Models.EditMaintainerViewModel

@{
ViewData["Title"] = "Edit Maintainer";
}

<div class="container-fluid">
@using (Html.BeginForm())
{
<div class="row">
<div class="col-md">
<span style="font-size: 1.2rem"><strong>Edit Maintainer</strong></span>
</div>
</div>
<hr />

@await Html.PartialAsync("Maintainer", Model)
;
}
</div>
Loading

0 comments on commit 3b01a3f

Please sign in to comment.