From 46ac6554c7171b65ebdc6eb028e58d9563066320 Mon Sep 17 00:00:00 2001 From: River Holstege Date: Fri, 3 Nov 2023 14:13:26 -0700 Subject: [PATCH 1/7] supervisor view, read only person stuff page --- Keas.Mvc/Controllers/SupervisorController.cs | 61 +++++ Keas.Mvc/Models/MyStaffListModel.cs | 78 ++++++ Keas.Mvc/Views/Supervisor/MyStaff.cshtml | 52 ++++ Keas.Mvc/Views/Supervisor/StaffStuff.cshtml | 250 +++++++++++++++++++ 4 files changed, 441 insertions(+) create mode 100644 Keas.Mvc/Controllers/SupervisorController.cs create mode 100644 Keas.Mvc/Models/MyStaffListModel.cs create mode 100644 Keas.Mvc/Views/Supervisor/MyStaff.cshtml create mode 100644 Keas.Mvc/Views/Supervisor/StaffStuff.cshtml diff --git a/Keas.Mvc/Controllers/SupervisorController.cs b/Keas.Mvc/Controllers/SupervisorController.cs new file mode 100644 index 000000000..d8e78ca50 --- /dev/null +++ b/Keas.Mvc/Controllers/SupervisorController.cs @@ -0,0 +1,61 @@ +using System; +using Keas.Core.Data; +using Keas.Mvc.Models; +using Keas.Mvc.Services; +using Microsoft.AspNetCore.Mvc; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Keas.Core.Helper; +using Microsoft.AspNetCore.Authorization; + +namespace Keas.Mvc.Controllers +{ + [Authorize] + public class SupervisorController : SuperController + { + private readonly ApplicationDbContext _context; + private readonly ISecurityService _securityService; + private readonly ITeamsManager _teamsManager; + + + public SupervisorController(ApplicationDbContext context, ISecurityService _securityService, IEventService _eventService, ITeamsManager teamsManager) + { + _context = context; + this._securityService = _securityService; + _teamsManager = teamsManager; + } + + public IActionResult RefreshPermissions() + { + _teamsManager.ClearTeams(); + return RedirectToAction("SelectTeam"); + } + + public async Task MyStaff() + { + var person = await _securityService.GetPerson(Team); + if(person == null){ + Message = "You are not yet added to the system."; + return RedirectToAction("NoAccess","Home"); + } + var viewmodel = await MyStaffListModel.Create(_context, person); + + return View(viewmodel); + } + + public async Task StaffStuff(int underlingId) + { + var supervisor = await _securityService.GetPerson(Team); + if(supervisor == null){ + Message = "You are not yet added to the system."; + return RedirectToAction("NoAccess","Home"); + } + var underling = await _context.People.Include(p=> p.Team).FirstOrDefaultAsync(p=> p.Id==underlingId && p.SupervisorId == supervisor.Id); + var viewmodel = await MyStaffListItem.Create(_context, underling); + + return View(viewmodel); + } + + } +} diff --git a/Keas.Mvc/Models/MyStaffListModel.cs b/Keas.Mvc/Models/MyStaffListModel.cs new file mode 100644 index 000000000..8ec24d593 --- /dev/null +++ b/Keas.Mvc/Models/MyStaffListModel.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using Keas.Core.Data; +using Keas.Core.Domain; +using System.Linq; +using System.Threading.Tasks; +using Keas.Mvc.Services; +using Microsoft.EntityFrameworkCore; +using System; +using System.Linq.Expressions; + +namespace Keas.Mvc.Models +{ + public class MyStaffListModel + { + public List People { get; set; } + + public static async Task Create(ApplicationDbContext context, Person person) + { + var viewModel = new MyStaffListModel + { + People = await context.People.Where(p => p.TeamId == person.TeamId && p.Active && p.SupervisorId == person.Id) + .Include(p => p.Team) + .OrderBy(p => p.LastName).ThenBy(p => p.FirstName) + .AsNoTracking().ToListAsync() + }; + return viewModel; + } + + } + + public class MyStaffListItem + { + public List KeySerials { get; set; } + public List Equipment { get; set; } + public List Access { get; set; } + public List Workstations { get; set; } + public List Documents { get; set; } + public Func DocumentUrlResolver { get; set; } + public List Histories { get; set; } + public bool PendingItems { get; set; } + public IEnumerable TeamsWithPendingAssignments { get; set; } + + + public static async Task Create(ApplicationDbContext context, Person person) + { + var viewModel = new MyStaffListItem + { + KeySerials = await context.KeySerials.Include(s=> s.Key).ThenInclude(k=> k.KeyXSpaces).ThenInclude(kxp=> kxp.Space).Include(s=> s.KeySerialAssignment) + .Where(s=> s.KeySerialAssignment.Person==person).AsNoTracking().ToListAsync(), + Equipment = await context.Equipment.Include(e => e.Space).Include(e=> e.Assignment).Where(e => e.Assignment.Person == person).AsNoTracking().ToListAsync(), + Access = await context.Access + .Where(x => x.Active && x.Assignments.Any(y => y.Person == person)) + .Select(a => new Access() + { + Id = a.Id, + Name = a.Name, + Assignments = a.Assignments.Where(b => b.Person == person).Select( + c => new AccessAssignment() + { + AccessId = c.AccessId, + ExpiresAt = c.ExpiresAt, + Id = c.Id + } + ).ToList() + }) + .AsNoTracking().ToListAsync(), + Workstations = await context.Workstations.Include(w=> w.Assignment).Include(w=> w.Space).Where(w=> w.Assignment.Person==person).AsNoTracking().ToListAsync(), + Documents = await context.Documents.Where(d => d.Person == person).AsNoTracking().ToListAsync(), + Histories = await context.Histories.Where(x => x.Target == person) + .OrderByDescending(x => x.ActedDate) + .Take(10).AsNoTracking().ToListAsync() + }; + + return viewModel; + } + + } +} diff --git a/Keas.Mvc/Views/Supervisor/MyStaff.cshtml b/Keas.Mvc/Views/Supervisor/MyStaff.cshtml new file mode 100644 index 000000000..0327a75d5 --- /dev/null +++ b/Keas.Mvc/Views/Supervisor/MyStaff.cshtml @@ -0,0 +1,52 @@ +@using Keas.Core.Extensions +@model Keas.Mvc.Models.MyStaffListModel + +@{ + ViewData["Title"] = "MyStaff"; +} + +
+
+
+
+

MyStaff

+
+
+
+
+
+
+
+

People

+
+
+ + + + + + + + + + @foreach (var person in Model.People) { + + + + + + } + @if(!Model.People.Any()){ + + + + } + +
NameEmailStuff
@Html.DisplayFor(modelItem => person.NameV2)@Html.DisplayFor(modelItem => person.Email) + @Html.ActionLink("View", "StaffStuff", "Supervisor", new { underlingId= @person.Id }) +
You do not supervise anyone.
+
+
+ +
+
diff --git a/Keas.Mvc/Views/Supervisor/StaffStuff.cshtml b/Keas.Mvc/Views/Supervisor/StaffStuff.cshtml new file mode 100644 index 000000000..1cfffe1ba --- /dev/null +++ b/Keas.Mvc/Views/Supervisor/StaffStuff.cshtml @@ -0,0 +1,250 @@ +@using Keas.Core.Extensions +@model Keas.Mvc.Models.MyStaffListItem + +@{ + ViewData["Title"] = "Staff Stuff"; +} +@if(Model.PendingItems){ + var currentSlug = TempData["TeamName"] as string; + if (Model.TeamsWithPendingAssignments.Any(a => a.Slug != null && a.Slug == currentSlug)) + { +
+
+

You have pending items!

+ Go to Accept page +
+
+ } + if (Model.TeamsWithPendingAssignments.Any(a => a.Slug != currentSlug)) + { +

You have items pending in other teams:

+ foreach (var teamWithPending in Model.TeamsWithPendingAssignments.Where(a => a.Slug != currentSlug)) + { +
+
+

You have pending items in team @teamWithPending.Name!

+ Go to Accept page +
+
+ } + } +} +
+
+
+
+

MyStuff

+
+
+
+
+
+
+
+

Keys

+
+
+
+ + + + + + + + + + + + @foreach (var serial in Model.KeySerials) { + + + + + + + + } + + @if (!Model.KeySerials.Any()) { + + + + } + +
CodeSerialNameExpirationAccepted?
@serial.Key.Code@serial.Number@serial.Key.Name@serial.KeySerialAssignment.ExpiresAt.ToShortDateString()@serial.KeySerialAssignment.ConfirmedAt.AcceptedWithDate()
You have no Keys assigned.
+
+
+
+
+
+

Equipment

+
+
+ + + + + + + + + + + + + + @foreach (var equipment in Model.Equipment) { + + + + + + + + + + } + @if(!Model.Equipment.Any()){ + + + + } + +
Serial NumberNameMakeModelRoomExpirationAccepted?
@equipment.SerialNumber@equipment.Name@equipment.Make@equipment.Model@equipment.Space?.ShortName@equipment.Assignment.ExpiresAt.ToShortDateString()@equipment.Assignment.ConfirmedAt.AcceptedWithDate()
You have no equipment assigned.
+
+
+ +
+
+
+

Access

+
+
+ + + + + + + + + @foreach (var access in Model.Access) { + + + + + } + @if(!Model.Access.Any()){ + + + + } + +
NameExpiration
@access.Name@access.Assignments.First().ExpiresAt.ToShortDateString()
You have no access assigned.
+
+
+ + +
+
+
+

Workstations

+
+
+ + + + + + + + + + + + @foreach (var workstation in Model.Workstations) { + + + + + + + } + @if(!Model.Workstations.Any()){ + + + + } + +
NameRoomExpirationAccepted?
@workstation.Title@workstation.Space.ShortName@workstation.Assignment.ExpiresAt.ToShortDateString()@workstation.Assignment.ConfirmedAt.AcceptedWithDate()
You have no workstations assigned.
+ +
+
+ +
+
+
+

Documents

+
+
+ + + + + + + + + + + + @foreach (var document in Model.Documents) { + + + + + + + } + @if(!Model.Workstations.Any()){ + + + + } + +
NameStatusDateLink
@document.Name@document.Status@(document.CompletedAt.HasValue ? document.CompletedAt : document.CreatedAt)View
You have no documents assigned.
+ +
+
+ +
+
+

History

+
+ + + + + + + + + @foreach (var history in Model.Histories) { + + + + + } + @if(!Model.Histories.Any()){ + + + + } + +
@history.ActedDate.ToShortDateString()@history.Description
No history to display
+
+
+ +
+
From 5e6f0819c0106700e6dd4eee7a000266a425de8e Mon Sep 17 00:00:00 2001 From: River Holstege Date: Fri, 3 Nov 2023 14:13:54 -0700 Subject: [PATCH 2/7] better staff stuff --- Keas.Mvc/Controllers/SupervisorController.cs | 7 +++++-- Keas.Mvc/Models/MyStaffListModel.cs | 2 ++ Keas.Mvc/Views/Supervisor/MyStaff.cshtml | 2 +- Keas.Mvc/Views/Supervisor/StaffStuff.cshtml | 14 +++++++------- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Keas.Mvc/Controllers/SupervisorController.cs b/Keas.Mvc/Controllers/SupervisorController.cs index d8e78ca50..446ab1a47 100644 --- a/Keas.Mvc/Controllers/SupervisorController.cs +++ b/Keas.Mvc/Controllers/SupervisorController.cs @@ -44,14 +44,17 @@ public async Task MyStaff() return View(viewmodel); } - public async Task StaffStuff(int underlingId) + public async Task StaffStuff(int id) // id of staff being viewed { var supervisor = await _securityService.GetPerson(Team); if(supervisor == null){ Message = "You are not yet added to the system."; return RedirectToAction("NoAccess","Home"); } - var underling = await _context.People.Include(p=> p.Team).FirstOrDefaultAsync(p=> p.Id==underlingId && p.SupervisorId == supervisor.Id); + var underling = await _context.People.Include(p=> p.Team).FirstOrDefaultAsync(p=> p.Id==id && p.SupervisorId == supervisor.Id); + if(underling == null){ + return RedirectToAction("AccessDenied","Account"); // is this the best way to do this? -river + } var viewmodel = await MyStaffListItem.Create(_context, underling); return View(viewmodel); diff --git a/Keas.Mvc/Models/MyStaffListModel.cs b/Keas.Mvc/Models/MyStaffListModel.cs index 8ec24d593..6678514fe 100644 --- a/Keas.Mvc/Models/MyStaffListModel.cs +++ b/Keas.Mvc/Models/MyStaffListModel.cs @@ -30,6 +30,7 @@ public static async Task Create(ApplicationDbContext context, public class MyStaffListItem { + public Person Person { get; set;} public List KeySerials { get; set; } public List Equipment { get; set; } public List Access { get; set; } @@ -45,6 +46,7 @@ public static async Task Create(ApplicationDbContext context, P { var viewModel = new MyStaffListItem { + Person = person, KeySerials = await context.KeySerials.Include(s=> s.Key).ThenInclude(k=> k.KeyXSpaces).ThenInclude(kxp=> kxp.Space).Include(s=> s.KeySerialAssignment) .Where(s=> s.KeySerialAssignment.Person==person).AsNoTracking().ToListAsync(), Equipment = await context.Equipment.Include(e => e.Space).Include(e=> e.Assignment).Where(e => e.Assignment.Person == person).AsNoTracking().ToListAsync(), diff --git a/Keas.Mvc/Views/Supervisor/MyStaff.cshtml b/Keas.Mvc/Views/Supervisor/MyStaff.cshtml index 0327a75d5..67d08d6f9 100644 --- a/Keas.Mvc/Views/Supervisor/MyStaff.cshtml +++ b/Keas.Mvc/Views/Supervisor/MyStaff.cshtml @@ -34,7 +34,7 @@ @Html.DisplayFor(modelItem => person.NameV2) @Html.DisplayFor(modelItem => person.Email) - @Html.ActionLink("View", "StaffStuff", "Supervisor", new { underlingId= @person.Id }) + @Html.ActionLink("View", "StaffStuff", "Supervisor", new { id= @person.Id }) } diff --git a/Keas.Mvc/Views/Supervisor/StaffStuff.cshtml b/Keas.Mvc/Views/Supervisor/StaffStuff.cshtml index 1cfffe1ba..0c795f0d5 100644 --- a/Keas.Mvc/Views/Supervisor/StaffStuff.cshtml +++ b/Keas.Mvc/Views/Supervisor/StaffStuff.cshtml @@ -33,7 +33,7 @@
-

MyStuff

+

@Model.Person.Name's Stuff

@@ -68,7 +68,7 @@ @if (!Model.KeySerials.Any()) { - You have no Keys assigned. + @Model.Person.Name has no Keys assigned. } @@ -107,7 +107,7 @@ } @if(!Model.Equipment.Any()){ - You have no equipment assigned. + @Model.Person.Name has no equipment assigned. } @@ -137,7 +137,7 @@ } @if(!Model.Access.Any()){ - You have no access assigned. + @Model.Person.Name has no access assigned. } @@ -173,7 +173,7 @@ } @if(!Model.Workstations.Any()){ - You have no workstations assigned. + @Model.Person.Name has no workstations assigned. } @@ -207,9 +207,9 @@ View } - @if(!Model.Workstations.Any()){ + @if(!Model.Documents.Any()){ - You have no documents assigned. + @Model.Person.Name has no documents assigned. } From f7322e91f4c721994ec61d71c8b6de400eb617f6 Mon Sep 17 00:00:00 2001 From: River Holstege Date: Fri, 3 Nov 2023 14:14:06 -0700 Subject: [PATCH 3/7] small typo fix --- Keas.Mvc/Views/Confirm/MyStuff.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Keas.Mvc/Views/Confirm/MyStuff.cshtml b/Keas.Mvc/Views/Confirm/MyStuff.cshtml index baf83a264..f8f49666f 100644 --- a/Keas.Mvc/Views/Confirm/MyStuff.cshtml +++ b/Keas.Mvc/Views/Confirm/MyStuff.cshtml @@ -207,7 +207,7 @@ View } - @if(!Model.Workstations.Any()){ + @if(!Model.Documents.Any()){ You have no documents assigned. From 16b30a8e3e5d5b0f20113e30fc952c7db5f8476b Mon Sep 17 00:00:00 2001 From: River Holstege Date: Fri, 3 Nov 2023 15:02:19 -0700 Subject: [PATCH 4/7] auth any role on all report pages but index --- Keas.Mvc/Controllers/ReportController.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Keas.Mvc/Controllers/ReportController.cs b/Keas.Mvc/Controllers/ReportController.cs index 23a5b2aae..a2b7b49c2 100644 --- a/Keas.Mvc/Controllers/ReportController.cs +++ b/Keas.Mvc/Controllers/ReportController.cs @@ -14,7 +14,6 @@ namespace Keas.Mvc.Controllers { - [Authorize(Policy = AccessCodes.Codes.AnyRole)] public class ReportController : SuperController { private readonly ApplicationDbContext _context; @@ -35,6 +34,7 @@ public async Task Index() return View(model); } + [Authorize(Policy = AccessCodes.Codes.AnyRole)] public async Task PersonActions(DateTime? startDate, DateTime? endDate) { var team = await _context.Teams.SingleAsync(a => a.Slug == Team); @@ -64,13 +64,14 @@ public async Task PersonActions(DateTime? startDate, DateTime? end return View(model); } + [Authorize(Policy = AccessCodes.Codes.AnyRole)] public async Task ExpiringItems(DateTime? expiresBefore = null, string showType = "All") { var model = await _reportService.ExpiringItems(null, Team, expiresBefore, showType); return View(model); } - + [Authorize(Policy = AccessCodes.Codes.AnyRole)] public async Task SupervisorDirectReports(int personID = 0) { var model = await SupervisorReportViewModel.Create(_context, Team, personID); @@ -132,6 +133,7 @@ public async Task PersonTeamList(int personId) } + [Authorize(Policy = AccessCodes.Codes.AnyRole)] public async Task UnAcceptedItems(string showType = "All") { var userRoles = await _securityService.GetUserRoleNamesInTeamOrAdmin(Team); @@ -140,6 +142,7 @@ public async Task UnAcceptedItems(string showType = "All") } + [Authorize(Policy = AccessCodes.Codes.AnyRole)] public async Task KeyValues() { var model = await KeyValueReportViewModel.Create(_context, Team); @@ -187,11 +190,13 @@ public async Task EquipmentHistoryReport(int id) return View(await _reportService.EquipmentHistory(null, Team, id)) ; } + [Authorize(Policy = AccessCodes.Codes.AnyRole)] public async Task PersonEquipmentHistoryReport(int id) { return View(await _reportService.PersonEquipmentHistory(null, Team, id)); } + [Authorize(Policy = AccessCodes.Codes.AnyRole)] public async Task AccessReport() { var accessList = await _reportService.AccessList(null, Team); @@ -238,6 +243,7 @@ public async Task CompletedDocuments(DateTime? start = null, Date return View(model); } + [Authorize(Policy = AccessCodes.Codes.AnyRole)] public async Task PeopleInTeam(bool hideInactive = true) { var team = await _context.Teams.SingleAsync(a => a.Slug == Team); @@ -256,6 +262,7 @@ public async Task PeopleInTeam(bool hideInactive = true) return View(model); } + [Authorize(Policy = AccessCodes.Codes.AnyRole)] public async Task PeopleLeavingWithAssets() { var theDate = DateTime.UtcNow.AddDays(30).Date; @@ -265,6 +272,7 @@ public async Task PeopleLeavingWithAssets() return View(peopleQuery); } + [Authorize(Policy = AccessCodes.Codes.AnyRole)] public async Task InActiveSpaces() { var spaceQuery = await _reportService.InactiveSpaces(Team); From 21ba264ff4e013f70341cec915df36ccb88166a0 Mon Sep 17 00:00:00 2001 From: River Holstege Date: Fri, 3 Nov 2023 15:02:59 -0700 Subject: [PATCH 5/7] hide general and people reports unless any role --- Keas.Mvc/Views/Report/Index.cshtml | 49 +++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/Keas.Mvc/Views/Report/Index.cshtml b/Keas.Mvc/Views/Report/Index.cshtml index b9c7cd96e..c8ad57edd 100644 --- a/Keas.Mvc/Views/Report/Index.cshtml +++ b/Keas.Mvc/Views/Report/Index.cshtml @@ -31,6 +31,9 @@ } + @if (Model.Contains(Role.Codes.KeyMaster) || Model.Contains(Role.Codes.EquipmentMaster) || Model.Contains(Role.Codes.AccessMaster) // basically Codes.AnyRole + || Model.Contains(Role.Codes.SpaceMaster) || Model.Contains(Role.Codes.DocumentMaster) || Model.Contains(Role.Codes.Admin) || Model.Contains(Role.Codes.PersonManager)) + {

People Reports

    @@ -54,6 +57,7 @@ }
+ } @if (Model.Contains(Role.Codes.SpaceMaster) || Model.Contains(Role.Codes.DepartmentalAdmin)) {
@@ -108,22 +112,37 @@
} -
-

General Reports

-
From db57242b75160befb2c49d34387e8f6c1bb0c866 Mon Sep 17 00:00:00 2001 From: River Holstege Date: Fri, 3 Nov 2023 15:03:11 -0700 Subject: [PATCH 6/7] always show reports tab? not sure about this --- Keas.Mvc/Views/Shared/_Layout.cshtml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Keas.Mvc/Views/Shared/_Layout.cshtml b/Keas.Mvc/Views/Shared/_Layout.cshtml index 8c4316c1f..2da994b82 100644 --- a/Keas.Mvc/Views/Shared/_Layout.cshtml +++ b/Keas.Mvc/Views/Shared/_Layout.cshtml @@ -139,6 +139,9 @@ + } if ((await AuthorizationService.AuthorizeAsync(User, AccessCodes.Codes.DepartmentAdminAccess)).Succeeded || (await AuthorizationService.AuthorizeAsync(User, AccessCodes.Codes.PersonManagerAccess)).Succeeded) From a2433a14a2fa13e328171257be38e32042fbc0de Mon Sep 17 00:00:00 2001 From: River Holstege Date: Fri, 3 Nov 2023 15:03:28 -0700 Subject: [PATCH 7/7] always show people on MyStuff? also not sure about this --- Keas.Mvc/Views/Confirm/MyStuff.cshtml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Keas.Mvc/Views/Confirm/MyStuff.cshtml b/Keas.Mvc/Views/Confirm/MyStuff.cshtml index f8f49666f..3570e0035 100644 --- a/Keas.Mvc/Views/Confirm/MyStuff.cshtml +++ b/Keas.Mvc/Views/Confirm/MyStuff.cshtml @@ -38,6 +38,16 @@
+
+
+
+

People

+
+
+ +