Skip to content

Commit

Permalink
Initial calendar implementation (#29)
Browse files Browse the repository at this point in the history
* Initial calendar setup completed, including the interface and frontend connection to the backend, along with a basic template for the assignment reader. The full integration with PCSS will come later. Features like Jump To Date, assignment displays inside the calendar cells and popups will also be added in the next phase.


* Initial Daashboard page implementation
  - Calendar UI updated as per wireframes
  - Events were Added
  - Side panels behavior
  - Locations, Activities and Presiders Load
  - Events Filtering added

* pcss-client added

- New Dashboard Structure;
- Initial PCSS Integration;

* Update package-lock.json using centos7 nodejs12


---------

Co-authored-by: Timaqt <TimA@QL023547701657>
Co-authored-by: Ronaldo Macapobre <[email protected]>
Co-authored-by: Wade Barnes <[email protected]>
  • Loading branch information
4 people authored Nov 22, 2024
1 parent 7c6710a commit 52cde11
Show file tree
Hide file tree
Showing 54 changed files with 4,969 additions and 69 deletions.
15 changes: 8 additions & 7 deletions SCV.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30011.22
# Visual Studio Version 17
VisualStudioVersion = 17.9.34723.18
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "api", "api\api.csproj", "{46FE5ADD-2BAF-47D0-BB0B-912F9ED4F743}"
EndProject
Expand All @@ -11,6 +10,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "tests", "tests\tests.csproj
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "db", "db\db.csproj", "{E15BEA58-373C-4A12-ABF8-7D1522DC8404}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pcss-client", "pcss-client\pcss-client.csproj", "{C1736008-CC5B-40AC-A0A4-48C85E49067F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -21,10 +22,6 @@ Global
{46FE5ADD-2BAF-47D0-BB0B-912F9ED4F743}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46FE5ADD-2BAF-47D0-BB0B-912F9ED4F743}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46FE5ADD-2BAF-47D0-BB0B-912F9ED4F743}.Release|Any CPU.Build.0 = Release|Any CPU
{B73D5408-1350-4C28-95D6-6977B2306E32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B73D5408-1350-4C28-95D6-6977B2306E32}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B73D5408-1350-4C28-95D6-6977B2306E32}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B73D5408-1350-4C28-95D6-6977B2306E32}.Release|Any CPU.Build.0 = Release|Any CPU
{5F6774A8-016E-4C12-9E00-08AC736FE8EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5F6774A8-016E-4C12-9E00-08AC736FE8EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5F6774A8-016E-4C12-9E00-08AC736FE8EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -37,6 +34,10 @@ Global
{E15BEA58-373C-4A12-ABF8-7D1522DC8404}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E15BEA58-373C-4A12-ABF8-7D1522DC8404}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E15BEA58-373C-4A12-ABF8-7D1522DC8404}.Release|Any CPU.Build.0 = Release|Any CPU
{C1736008-CC5B-40AC-A0A4-48C85E49067F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C1736008-CC5B-40AC-A0A4-48C85E49067F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C1736008-CC5B-40AC-A0A4-48C85E49067F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C1736008-CC5B-40AC-A0A4-48C85E49067F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
127 changes: 127 additions & 0 deletions api/Controllers/DashboardController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Scv.Api.Helpers.Extensions;
using Scv.Api.Infrastructure.Authorization;
using Scv.Api.Services;
using Scv.Api.Models.Lookup;
using PCSS.Models.REST.JudicialCalendar;
using Scv.Api.Helpers;
using Scv.Api.Models.Calendar;

namespace Scv.Api.Controllers
{
[Authorize(AuthenticationSchemes = "SiteMinder, OpenIdConnect", Policy = nameof(ProviderAuthorizationHandler))]
[Route("api/[controller]")]
[ApiController]
public class DashboardController : ControllerBase
{
#region Variables
private readonly LocationService _locationService;
private readonly JudicialCalendarService _judicialCalendarService;

#endregion Variables

#region Constructor
public DashboardController(LocationService locationService, JudicialCalendarService judicialCalendarService)
{
_locationService = locationService;
_judicialCalendarService = judicialCalendarService;
}
#endregion Constructor

/// <summary>
/// Returns list of assignemnts for a given month and year for current user.
/// </summary>
/// <param name="year">selected year</param>
/// <param name="month">selected month</param>
/// <param name="locationId">selected month</param>
/// <returns></returns>
// [HttpGet("monthly-schedule/{year}/{month}")]
[HttpGet]
[Route("monthly-schedule/{year}/{month}")]
public async Task<ActionResult<CalendarSchedule>> GetMonthlySchedule(int year, int month, [FromQuery] string locationId = "")
{
try
{
// first day of the month and a week before the first day of the month
var startDate = new DateTime(year, month, 1).AddDays(-7);
// last day of the month and a week after the last day of the month
var endDate = startDate.AddMonths(1).AddDays(-1).AddDays(7);
var calendars = await _judicialCalendarService.JudicialCalendarsGetAsync(locationId, startDate, endDate);
CalendarSchedule calendarSchedule = new CalendarSchedule();

var calendarDays = MapperHelper.CalendarToDays(calendars.ToList());
if (calendarDays == null)
{
calendarSchedule.Schedule = new List<CalendarDay>();
}
else
calendarSchedule.Schedule = calendarDays;

calendarSchedule.Presiders = calendars.Where(t => t.IsPresider).Select(presider => new FilterCode
{
Text = $"{presider.RotaInitials} - {presider.Name}",
Value = $"{presider.ParticipantId}",
}).DistinctBy(t => t.Value).OrderBy(x => x.Value).ToList();

var assignmentsList = calendars.Where(t => t.IsPresider)
.Where(t => t.Days?.Count > 0)
.SelectMany(t => t.Days).Where(day => day.Assignment != null && (day.Assignment.ActivityAm !=null || day.Assignment.ActivityPm != null))
.Select(day => day.Assignment)
.ToList();
var activitiesList = assignmentsList
.SelectMany(t => new[] { t.ActivityAm, t.ActivityPm })
.Where(activity => activity != null)
.Select(activity => new FilterCode
{
Text = activity.ActivityDescription,
Value = activity.ActivityCode
})
.DistinctBy(t => t.Value)
.OrderBy(x => x.Text)
.ToList();
calendarSchedule.Activities = activitiesList;

return Ok(calendarSchedule);
}
catch (Exception ex)
{
// Log the exception
return StatusCode(500, "Internal server error");
}
}

//public async Task<ActionResult<List<FilterCode>>> LocationList(int a)
/// <summary>
/// Provides locations.
/// </summary>
/// <returns>IEnumerable{FilterCode}</returns>
[HttpGet]
[Route("locations")]
public async Task<ActionResult<IEnumerable<FilterCode>>> LocationList()
{
try
{
var locations = await _locationService.GetLocations();
var locationList = locations.Where(t => t.Flex?.Equals("Y") == true).Select(location => new FilterCode
{
Text = location.LongDesc,
Value = location.ShortDesc
}).OrderBy(x => x.Text);

return Ok(locationList);
}
catch (Exception ex)
{
// Log the exception
return StatusCode(500, "Internal server error" + ex.Message);
}
}
}


}
21 changes: 21 additions & 0 deletions api/Helpers/MapperHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using AutoMapper;
using System.Collections.Generic;
using Scv.Api.Models.Calendar;
using Scv.Api.Mappers;
using PCSS.Models.REST.JudicialCalendar;
using System.Linq;

namespace Scv.Api.Helpers
{
public static class MapperHelper
{
// Usage
public static List<CalendarDay> CalendarToDays(List<JudicialCalendar> listOfCalendars)
{
var config = new MapperConfiguration(cfg => cfg.AddProfile<MappingProfile>());
var mapper = new Mapper(config);

return listOfCalendars.SelectMany(calendarDays => mapper.Map<List<CalendarDay>>(calendarDays)).ToList();
}
}
}
7 changes: 7 additions & 0 deletions api/Infrastructure/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
using Scv.Api.Services.Files;
using BasicAuthenticationHeaderValue = JCCommon.Framework.BasicAuthenticationHeaderValue;
using Scv.Api.Infrastructure.Handler;
using PCSSClient.Clients.JudicialCalendarsServices;
using PCSSClient.Clients.CourtCalendarsServices;


namespace Scv.Api.Infrastructure
{
Expand Down Expand Up @@ -84,6 +87,10 @@ public static IServiceCollection AddHttpClientsAndScvServices(this IServiceColle
services.AddScoped<VcCivilFileAccessHandler>();
services.AddSingleton<JCUserService>();
services.AddSingleton<AesGcmEncryption>();
services.AddSingleton<JudicialCalendarService>();

services.AddSingleton<JudicialCalendarsServicesClient>();
services.AddSingleton<CourtCalendarsServicesClient>();

return services;
}
Expand Down
30 changes: 30 additions & 0 deletions api/Mappers/Mapping.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using Scv.Api.Controllers;
using Scv.Api.Services;
using Scv.Api.Models;
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Collections.Generic;
using PCSS.Models.REST.JudicialCalendar;
using Scv.Api.Models.Calendar;
using System.Linq;

namespace Scv.Api.Mappers
{
public class MappingProfile : AutoMapper.Profile
{
public MappingProfile()
{
CreateMap<JudicialCalendarDay, CalendarDay>();


CreateMap<JudicialCalendar, List<CalendarDay>>()
.ConvertUsing((src, dest, context) =>
src.Days.Select(b => {
var c = context.Mapper.Map<CalendarDay>(b);
c.RotaInitials = src.RotaInitials;
return c;
}).ToList());
}
}

}
46 changes: 46 additions & 0 deletions api/Models/Calendar/CalendarDay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using PCSS.Models.REST.JudicialCalendar;
using System;

namespace Scv.Api.Models.Calendar
{
public class CalendarDay : JudicialCalendarDay
{
public string RotaInitials { get; set; }
public DateTime Start
{
get
{
return DateTime.ParseExact(base.Date, "dd-MMM-yyyy", null).AddHours(8);
}
}

public bool showAM
{
get
{
return showPM;
}
}
public bool showPM
{
get
{
if(showPMLocation || (this.Assignment?.ActivityAm?.CourtRoomCode != this.Assignment?.ActivityPm?.CourtRoomCode)
|| (this.Assignment?.ActivityAm?.ActivityDescription != this.Assignment?.ActivityPm?.ActivityDescription))
return true;
else
return false;
}
}
public bool showPMLocation
{
get
{
if (this.Assignment?.ActivityPm != null && this.Assignment?.ActivityAm?.LocationName != this.Assignment?.ActivityPm?.LocationName)
return true;
else
return false;
}
}
}
}
12 changes: 12 additions & 0 deletions api/Models/Calendar/CalendarSchedule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Scv.Api.Models.Lookup;
using System.Collections.Generic;

namespace Scv.Api.Models.Calendar
{
public class CalendarSchedule
{
public List<CalendarDay> Schedule { get; set; }
public List<FilterCode> Activities { get; set; }
public List<FilterCode> Presiders { get; set; }
}
}
8 changes: 8 additions & 0 deletions api/Models/Lookup/FilterCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Scv.Api.Models.Lookup
{
public class FilterCode
{
public string Text { get; set; }
public string Value { get; set; }
}
}
73 changes: 73 additions & 0 deletions api/Services/JudicialCalendarService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using JCCommon.Clients.LocationServices;
using LazyCache;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Serialization;
using PCSSClient.Clients.JudicialCalendarsServices;
using Scv.Api.Helpers;
using Scv.Api.Helpers.ContractResolver;
using System;
using System.Linq;
using System.Threading.Tasks;
using PCSS.Models.REST.JudicialCalendar;
using System.Collections.Generic;
using System.Threading;

namespace Scv.Api.Services
{
/// <summary>
/// This should handle caching and JudicialCalendarsServicesClient.
/// </summary>
public class JudicialCalendarService
{
#region Variables

private readonly IAppCache _cache;
private readonly IConfiguration _configuration;
private JudicialCalendarsServicesClient _judicialCalendarsClient { get; }

#endregion Variables

#region Properties

#endregion Properties

#region Constructor

public JudicialCalendarService(IConfiguration configuration, JudicialCalendarsServicesClient judicialCalendarsClient,
IAppCache cache)
{
_configuration = configuration;
_judicialCalendarsClient = judicialCalendarsClient;
_cache = cache;
_cache.DefaultCachePolicy.DefaultCacheDurationSeconds = int.Parse(configuration.GetNonEmptyValue("Caching:LocationExpiryMinutes")) * 60;
SetupLocationServicesClient();
}

#endregion Constructor

#region Collection Methods

public async Task<ICollection<JudicialCalendar>> JudicialCalendarsGetAsync(string locationId, DateTime startDate, DateTime endDate)
{
var judicialCalendars = await _judicialCalendarsClient.JudicialCalendarsGetAsync(locationId, startDate, endDate, CancellationToken.None);

return judicialCalendars;
}


#endregion Collection Methods

#region Lookup Methods


#endregion Lookup Methods

#region Helpers
private void SetupLocationServicesClient()
{
_judicialCalendarsClient.JsonSerializerSettings.ContractResolver = new SafeContractResolver { NamingStrategy = new CamelCaseNamingStrategy() };
}

#endregion Helpers
}
}
Loading

0 comments on commit 52cde11

Please sign in to comment.