Skip to content

Commit

Permalink
Feature schedule ui (#64)
Browse files Browse the repository at this point in the history
* Initial schedule UI work

* Revert "Initial schedule UI"

* Fix variable height with DayPicker component by adding an extra row to CSS Grid

* Now passing schedule information around:

* Now passing schedule state between components

* Completed initial UI for scheduleitems

* Now saving recurring schedules

* Started work on the RecurrenceDataEntry component

* Now doing initial calculations of CRON pattern

* Highlight the date clicked in the DayPicker component

* DayView appointments are positioned correctly and DayView appointments outside the time range are not displayed. Also, Add graphical representation for a schedule item that begins before or after the DayView.

* Refactoring DayView so that we can make a ManagerScheduleView

* Fixed schedule item display on the DayView

* Fixed some display issues, corrected expansion of the schedule

* Fixed small bug in top and bottom styles of items in DayView

* Updated DayView to properly show the week grid for Managers

* Fixed overflow issue with items in DayView

* Started work on calculating employee availability

* Now calculating availability

* Finished Resource Availability test

* Issue #8 - domain object validation (#34)

* issue #8 inital commit

* Issue #8 Cron validation in RecurringSchedule.cs

* more validation rules issue #8

* validation rules for default datetimes issue #8

* Issue #35 - Add support for fluent assertions (#39)

* Added FluentAssertions V5.7.0 NuGet package dependency

* Updated WhenExpandingSchedule tests to use FluentAssertions

* Updated WhenExpandingScheduleAcrossMultipleDays tests to use FluentAssertions

* Updated WhenExpandingSchedule tests to use FluentAssertions

* Issue #33 date time extensions, issue #30 (#38)

* Date time extensions issue #33

* xml comments + renames issue #33

* xml comment i missed issue #33

* removing extension methods for comparing Date with Time issue #33

* added authorization for pages where users must be logged in issue #30

* Completed grain calculations for ManagerView

* Updated to 3.0 preview 7

* Completed conversion to Preview 7 and now using sqlite

* Migrating to Client-side Blazor

* Migrating the components to the Client project

* Finishing merge

* Finished migrating components

* #56: Refactored code out of Availability page into AvailabilityViewModel

* #56 Pulled DayView attribute code out into ViewModel

* #56: Refactored code out of DayPicker into DayPickerViewModel

* #56: Pulled DisplayDayOfMonth rendering logic out into ViewModel

* #56 Added missing DI for DayPickerViewModel

* #56: Refactored code out of DayView into DayViewViewModel

* #56 - Refactored code out of ManagerScheduleView into ManagerScheduleViewViewModel

* #56 Standardised naming for Base component overrides on view models

* #56 Resolved error in Blazor markup - CS1660 C# Cannot convert lambda expression to type 'object' because it is not a delegate type

* #56 - Refactored code out of ManagerScheduleView into ManagerScheduleViewViewModel

* #56 - Refactored code out of NavMenu into NavMenuViewModel

* #56 Refactored ViewModel DI into IServiceCollection Extension method.

* WIP

* Marking the TODO unit test as debug only

* Added BlazorStrap and CSS for header and navbar

* Fixed component references so they now render

* Finished security connection

* Enhanced the formatting of the navbar and login components
  • Loading branch information
csharpfritz authored Aug 2, 2019
1 parent d937302 commit 8ea37b9
Show file tree
Hide file tree
Showing 101 changed files with 3,510 additions and 1,156 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*.userosscache
*.sln.docstates
.vscode/
*.db

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
Expand Down
31 changes: 31 additions & 0 deletions src/Fritz.ResourceManagement.Domain/ExtensionMethods.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Fritz.ResourceManagement.Domain
{
public static class ExtensionMethods
{

public static int? GetPersonId(this System.Security.Claims.ClaimsPrincipal claimsPrincipal)
{

return claimsPrincipal.GetClaimValueAsInt(UserInfo.Claims.PERSONID);

}

public static int? GetClaimValueAsInt(this System.Security.Claims.ClaimsPrincipal claimsPrincipal, string claimName)
{

var outValue = claimsPrincipal.Claims
.First(c => c.Type == claimName)?.Value;

if (string.IsNullOrEmpty(outValue)) return null;

return int.Parse(outValue);

}

}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.ComponentModel.Annotations" Version="4.6.0-preview7.19362.9" />
<PackageReference Include="CronEspresso" Version="3.0.0" />
</ItemGroup>

</Project>
42 changes: 32 additions & 10 deletions src/Fritz.ResourceManagement.Domain/Person.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,52 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using System.Data;

namespace Fritz.ResourceManagement.Domain
{
public class Person
{

public int Id { get; set; }
public int Id { get; set; }

public string GivenName { get; set; }
public string GivenName { get; set; }

public string MiddleName { get; set; }
public string MiddleName { get; set; }

public string SurName { get; set; }
public string SurName { get; set; }

public IList<PersonPersonType> PersonPersonType { get; set; }
public IList<PersonPersonType> PersonPersonType { get; set; }

public string PhoneNumber { get; set; }
public string PhoneNumber { get; set; }

public Schedule Schedule { get; set; }
public Schedule Schedule { get; set; }

#region Foreign Keys
#region Foreign Keys

public int ScheduleId { get; set; }
public int ScheduleId { get; set; }

#endregion
#endregion

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{

var results = new List<ValidationResult>();

if (string.IsNullOrWhiteSpace(GivenName))
results.Add(new ValidationResult($"{nameof(GivenName)} cannot be null, empty or consist of whitespace only", new[] { nameof(GivenName) }));

if (string.IsNullOrEmpty(SurName))
results.Add(new ValidationResult($"{nameof(SurName)} cannot be null, empty or consist of whitespace only", new[] { nameof(GivenName) }));

if (string.IsNullOrWhiteSpace(PhoneNumber))
results.Add(new ValidationResult($"{nameof(PhoneNumber)} cannot be null, empty or consist of whitespace only", new[] { nameof(PhoneNumber) }));

if (PersonPersonType.Count == 0)
results.Add(new ValidationResult($"{nameof(PersonPersonType)} must contain atleast 1 item", new[] { nameof(PersonPersonType) }));

return results;
}

}

Expand Down
2 changes: 1 addition & 1 deletion src/Fritz.ResourceManagement.Domain/PersonPersonType.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Fritz.ResourceManagement.Domain
namespace Fritz.ResourceManagement.Domain
{
public class PersonPersonType {

Expand Down
15 changes: 14 additions & 1 deletion src/Fritz.ResourceManagement.Domain/PersonType.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace Fritz.ResourceManagement.Domain
{
Expand All @@ -13,6 +14,18 @@ public class PersonType

public ICollection<PersonPersonType> PersonPersonTypes { get; set; }

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{

var results = new List<ValidationResult>();

if (string.IsNullOrWhiteSpace(Name))
results.Add(new ValidationResult($"{nameof(Name)} cannot be null, empty or consist of only whitespace", new[] { nameof(Name) }));

return results;

}

}

}
68 changes: 55 additions & 13 deletions src/Fritz.ResourceManagement.Domain/RecurringSchedule.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,72 @@
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Threading;
using CronEspresso.NETCore.Utils;

namespace Fritz.ResourceManagement.Domain
{
/// <summary>
/// An event that re-occurs on the schedule given a recurrence pattern defined in CronPattern
/// </summary>
public class RecurringSchedule {
/// <summary>
/// An event that re-occurs on the schedule given a recurrence pattern defined in CronPattern
/// </summary>
public class RecurringSchedule
{

public int Id { get; set; }
public int Id { get; set; }

public int ScheduleId { get; set; }
public int ScheduleId { get; set; }

public ScheduleStatus Status { get; set; }
public ScheduleStatus Status { get; set; }

public string Name { get; set; }
public string Name { get; set; }

public string CronPattern { get; set; }
public string CronPattern { get; set; }

public TimeSpan Duration { get; set; }
public TimeSpan Duration { get; set; }

[NotMapped()]
public string DurationText {
get { return Duration.ToString(); }
set { Duration = TimeSpan.Parse(value); }
}

public DateTime MinStartDateTime { get; set; }

public DateTime MaxEndDateTime { get; set; }
public DateTime MaxEndDateTime { get; set; }

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{

var results = new List<ValidationResult>();

if (string.IsNullOrWhiteSpace(Name))
results.Add(new ValidationResult($"{nameof(Name)} cannot be null, empty or consist of only whitespace", new[] { nameof(Name) }));

if (string.IsNullOrWhiteSpace(CronPattern))
results.Add(new ValidationResult($"{nameof(CronPattern)} is required", new[] { nameof(CronPattern) }));
else
{
var cronValidationResult = CronHelpers.ValidateCron(CronPattern);
if (!cronValidationResult.IsValidCron)
results.Add(new ValidationResult($"{nameof(CronPattern) } is not a valid Cron pattern, {cronValidationResult.ValidationMessage}", new[] { nameof(CronPattern) }));
}

if (Duration.TotalMinutes < 30)
results.Add(new ValidationResult($"{nameof(Duration)} must be atleast 30 minutes", new[] { nameof(Duration) }));

if (MinStartDateTime == default)
results.Add(new ValidationResult($"{nameof(MinStartDateTime)} is required", new[] { nameof(MinStartDateTime) }));

if (MaxEndDateTime == default)
results.Add(new ValidationResult($"{nameof(MaxEndDateTime)} is required", new[] { nameof(MaxEndDateTime) }));

if (MaxEndDateTime < MinStartDateTime)
results.Add(new ValidationResult($"{nameof(MaxEndDateTime)} cannot be before {nameof(MinStartDateTime)}", new[] { nameof(MaxEndDateTime), nameof(MinStartDateTime) }));

}
return results;
}

}

}
32 changes: 25 additions & 7 deletions src/Fritz.ResourceManagement.Domain/ScheduleException.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace Fritz.ResourceManagement.Domain
{
public class ScheduleException {
public class ScheduleException
{

public int Id { get; set; }
public int Id { get; set; }

public DateTime StartDateTime { get; set; }
public DateTime StartDateTime { get; set; }

public DateTime EndDateTime { get; set; }
public DateTime EndDateTime { get; set; }

public string Name { get; set; }
public string Name { get; set; }

}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{

var results = new List<ValidationResult>();

if (string.IsNullOrWhiteSpace(Name))
results.Add(new ValidationResult($"{nameof(Name)} cannot be null, empty or consist of only whitespace", new[] { nameof(Name) }));

if (EndDateTime < StartDateTime)
results.Add(new ValidationResult($"{nameof(EndDateTime)} cannot be before {nameof(StartDateTime)}", new[] { nameof(StartDateTime), nameof(EndDateTime) }));
else if (EndDateTime < StartDateTime.AddDays(10))
results.Add(new ValidationResult($"{nameof(EndDateTime)} must be atleast 1 day after {nameof(StartDateTime)}", new[] { nameof(StartDateTime), nameof(EndDateTime) }));

return results;

}
}
}
18 changes: 17 additions & 1 deletion src/Fritz.ResourceManagement.Domain/ScheduleItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,24 @@ public IEnumerable<ValidationResult> Validate(ValidationContext validationContex

var results = new List<ValidationResult>();

if (Status == default)
results.Add(new ValidationResult($"{nameof(Status)} is required", new[] { nameof(Status) }));

if (string.IsNullOrWhiteSpace(Name))
results.Add(new ValidationResult($"{nameof(Name)} cannot be null, empty or consist of whitespace only", new[] { nameof(Name) }));
else if (Name.Length > 50)
results.Add(new ValidationResult($"{nameof(Name)} is greater than max length of 50", new[] { nameof(Name) }));

if(StartDateTime == default)
results.Add(new ValidationResult($"{nameof(StartDateTime)} is required", new[] { nameof(StartDateTime) }));

if (EndDateTime == default)
results.Add(new ValidationResult($"{nameof(EndDateTime)} is required", new[] { nameof(EndDateTime) }));

if (EndDateTime < StartDateTime)
results.Add(new ValidationResult("EndDateTime cannot be before StartDateTime", new[] { nameof(StartDateTime), nameof(EndDateTime) }));
results.Add(new ValidationResult($"{nameof(EndDateTime)} cannot be before {nameof(StartDateTime)}", new[] { nameof(StartDateTime), nameof(EndDateTime) }));
else if (EndDateTime < StartDateTime.AddMinutes(10))
results.Add(new ValidationResult($"{nameof(EndDateTime)} must be atleast 10 minutes after {nameof(StartDateTime)}", new[] { nameof(StartDateTime), nameof(EndDateTime) }));

return results;

Expand Down
4 changes: 2 additions & 2 deletions src/Fritz.ResourceManagement.Domain/ScheduleStatus.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Fritz.ResourceManagement.Domain
namespace Fritz.ResourceManagement.Domain
{
public enum ScheduleStatus {
public enum ScheduleStatus {

Tentative,
NotAvailable,
Expand Down
41 changes: 37 additions & 4 deletions src/Fritz.ResourceManagement.Domain/TimeSlot.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,49 @@
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;

namespace Fritz.ResourceManagement.Domain
{
[DebuggerDisplay("{Name}: {StartDateTime}-{EndDateTime}")]
public class TimeSlot {

public DateTime StartDateTime { get; set; }
public string Name { get; set; }

public DateTime EndDateTime { get; set; }
public DateTime StartDateTime { get; set; }

public DateTime EndDateTime { get; set; }

public TimeSpan Duration { get { return EndDateTime.Subtract(StartDateTime); } }

public ScheduleStatus Status { get; set; }

public bool Overlaps(TimeSlot ts2)
{

}
return this.StartDateTime <= ts2.EndDateTime && this.EndDateTime >= ts2.StartDateTime;

}

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{

var results = new List<ValidationResult>();

if (Status == default)
results.Add(new ValidationResult($"{nameof(Status)} cannot have the default value of {default(ScheduleStatus)}", new[] { nameof(Status) }));

if (StartDateTime == default)
results.Add(new ValidationResult($"{nameof(StartDateTime)} is required", new[] { nameof(StartDateTime) }));

if (EndDateTime == default)
results.Add(new ValidationResult($"{nameof(EndDateTime)} is required", new[] { nameof(EndDateTime) }));

if (EndDateTime < StartDateTime)
results.Add(new ValidationResult($"{nameof(EndDateTime)} cannot be before {nameof(StartDateTime)}", new[] { nameof(StartDateTime), nameof(EndDateTime) }));

return results;

}
}
}
10 changes: 10 additions & 0 deletions src/Fritz.ResourceManagement.Domain/TimeSlotAvailability.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Fritz.ResourceManagement.Domain
{
public class TimeSlotAvailability : TimeSlot
{

public int Count { get; set; }

}

}
10 changes: 10 additions & 0 deletions src/Fritz.ResourceManagement.Domain/TimeUnit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Fritz.ResourceManagement.Domain
{
public enum AvailabilityTimeUnit
{
HalfHour = 30,
Hour = 60,
Day = 1440
}

}
Loading

0 comments on commit 8ea37b9

Please sign in to comment.