Skip to content
This repository has been archived by the owner on Sep 4, 2023. It is now read-only.

Commit

Permalink
Merge branch 'develop' into feat/124-generic-canvas-pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Koen Janssen committed Jun 9, 2023
2 parents f7b82b7 + d1d7c41 commit c8e3a9c
Show file tree
Hide file tree
Showing 15 changed files with 133 additions and 78 deletions.
11 changes: 8 additions & 3 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ dotnet_style_qualification_for_property = false:error
dotnet_style_require_accessibility_modifiers = for_non_interface_members:error

# ReSharper properties
resharper_align_multiline_calls_chain = true
resharper_apply_auto_detected_rules = false
resharper_blank_lines_after_control_transfer_statements = 1
resharper_braces_for_for = required
Expand All @@ -140,9 +141,10 @@ resharper_braces_for_while = required
resharper_braces_redundant = false
resharper_csharp_blank_lines_around_single_line_invocable = 1
resharper_csharp_case_block_braces = next_line_shifted_2
resharper_csharp_max_line_length = 176
resharper_csharp_max_line_length = 180
resharper_csharp_remove_blank_lines_near_braces_in_declarations = false
resharper_csharp_wrap_after_declaration_lpar = true
resharper_csharp_wrap_arguments_style = chop_if_long
resharper_csharp_wrap_before_declaration_rpar = true
resharper_csharp_wrap_before_first_type_parameter_constraint = true
resharper_csharp_wrap_extends_list_style = chop_if_long
Expand All @@ -154,6 +156,7 @@ resharper_formatter_on_tag = @formatter:on
resharper_formatter_tags_enabled = true
resharper_instance_members_qualify_declared_in =
resharper_keep_existing_initializer_arrangement = false
resharper_keep_existing_list_patterns_arrangement = false
resharper_max_attribute_length_for_same_line = 64
resharper_new_line_before_while = true
resharper_object_creation_when_type_evident = explicitly_typed
Expand All @@ -164,15 +167,17 @@ resharper_place_accessor_attribute_on_same_line = false
resharper_place_constructor_initializer_on_same_line = false
resharper_place_expr_method_on_single_line = true
resharper_place_expr_property_on_single_line = true
resharper_place_field_attribute_on_same_line = false
resharper_place_record_field_attribute_on_same_line = true
resharper_place_simple_embedded_statement_on_same_line = false
resharper_place_simple_initializer_on_single_line = false
resharper_place_simple_initializer_on_single_line = true
resharper_show_autodetect_configure_formatting_tip = false
resharper_trailing_comma_in_multiline_lists = true
resharper_trailing_comma_in_singleline_lists = true
resharper_use_indent_from_vs = false
resharper_wrap_array_initializer_style = chop_always
resharper_wrap_array_initializer_style = chop_if_long
resharper_wrap_before_eq = true
resharper_wrap_list_pattern = chop_if_long
resharper_wrap_object_and_collection_initializer_style = chop_always
resharper_wrap_property_pattern = chop_always

Expand Down
12 changes: 0 additions & 12 deletions Epsilon.Abstractions/Component/CompetenceComponentNameAttribute.cs

This file was deleted.

17 changes: 6 additions & 11 deletions Epsilon.Abstractions/Component/CompetenceProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,24 @@

namespace Epsilon.Abstractions.Component;

[CompetenceComponentName("competence_profile")]
public record CompetenceProfile(
IHboIDomain HboIDomain,
IEnumerable<ProfessionalTaskResult> ProfessionalTaskOutcomes,
IEnumerable<ProfessionalSkillResult> ProfessionalSkillOutcomes,
IEnumerable<EnrollmentTerm> Terms
) : ICompetenceWordComponent
IEnumerable<ProfessionalSkillResult> ProfessionalSkillOutcomes
) : IWordCompetenceComponent
{
public void AddToWordDocument(MainDocumentPart mainDocumentPart)
{
// TODO: This is simply an example to show the capability of the component architecture
var body = new Body();

foreach (var enrollmentTerm in Terms)
{
body.AppendChild(
new Paragraph(
new Run(
new Text(enrollmentTerm.Name)
body.AppendChild(
new Paragraph(
new Run(
new Text("Competence profile comes here")
)
)
);
}

// mainDocumentPart.Document.AppendChild(body);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Epsilon.Abstractions.Component;

public interface ICompetenceWordComponent : ICompetenceComponent
public interface IWordCompetenceComponent : ICompetenceComponent
{
public void AddToWordDocument(MainDocumentPart mainDocumentPart);
}
3 changes: 1 addition & 2 deletions Epsilon.Abstractions/Component/KpiMatrixCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@

namespace Epsilon.Abstractions.Component;

[CompetenceComponentName("kpi_matrix")]
public record KpiMatrixCollection(
IEnumerable<KpiMatrixAssignment> KpiMatrixAssignments,
IDictionary<OutcomeGradeStatus, KpiMatrixOutcomeGradeStatus> GradeStatus
) : ICompetenceWordComponent
) : IWordCompetenceComponent
{
public static readonly IDictionary<OutcomeGradeStatus, KpiMatrixOutcomeGradeStatus> DefaultGradeStatus = new Dictionary<OutcomeGradeStatus, KpiMatrixOutcomeGradeStatus>
{
Expand Down
3 changes: 1 addition & 2 deletions Epsilon.Abstractions/Component/PersonaPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

namespace Epsilon.Abstractions.Component;

[CompetenceComponentName("persona")]
public record PersonaPage(string PersonaHtml) : ICompetenceWordComponent
public record PersonaPage(string PersonaHtml) : IWordCompetenceComponent
{
public void AddToWordDocument(MainDocumentPart mainDocumentPart)
{
Expand Down
9 changes: 9 additions & 0 deletions Epsilon.Abstractions/Service/IFilterService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Epsilon.Abstractions.Component;
using Epsilon.Canvas.Abstractions.Model;

namespace Epsilon.Abstractions.Service;

public interface IFilterService
{
Task<IEnumerable<EnrollmentTerm>> GetParticipatedTerms();
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;

namespace Epsilon.Canvas.Abstractions.Model.GraphQl;

public record SubmissionsConnectionNode(
[property: JsonPropertyName("submittedAt")] DateTime? SubmittedAt,
[property: JsonPropertyName("postedAt")] DateTime? PostedAt,
[property: JsonPropertyName("assignment")] Assignment? Assignment,
[property: JsonPropertyName("submissionHistoriesConnection")] SubmissionsHistoriesConnection SubmissionsHistories,
Expand Down
2 changes: 1 addition & 1 deletion Epsilon.Canvas/Service/AccountHttpService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Net.Http.Json;
using System.Net.Http.Json;
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Service;
using Epsilon.Canvas.Http;
Expand Down
23 changes: 23 additions & 0 deletions Epsilon.Host.WebApi/Controllers/FilterController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Epsilon.Abstractions.Service;
using Epsilon.Canvas.Abstractions.Model;
using Microsoft.AspNetCore.Mvc;

namespace Epsilon.Host.WebApi.Controllers;

[ApiController]
[Route("[controller]")]
public class FilterController : Controller
{
private readonly IFilterService _filterService;

public FilterController(IFilterService filterService)
{
_filterService = filterService;
}

[HttpGet("participated-terms")]
public async Task<IEnumerable<EnrollmentTerm>> GetParticipatedTerms()
{
return await _filterService.GetParticipatedTerms();
}
}
18 changes: 10 additions & 8 deletions Epsilon.Host.WebApi/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Epsilon.Abstractions.Component;
using Epsilon.Abstractions.Service;
using Epsilon.Canvas;
using Epsilon.Component;
using Epsilon.Service;

var builder = WebApplication.CreateBuilder(args);
Expand All @@ -14,7 +13,7 @@
options.AddDefaultPolicy(policy =>
{
policy.WithOrigins(builder.Configuration["Lti:TargetUri"])
.AllowCredentials();
.AllowCredentials();
});
});

Expand All @@ -25,13 +24,16 @@

builder.Services.AddCanvas(canvasConfiguration);

builder.Services.AddScoped<IFilterService, FilterService>();
builder.Services.AddScoped<ICompetenceDocumentService, CompetenceDocumentService>();
builder.Services.AddScoped<ICompetenceComponentService, CompetenceComponentService>();

builder.Services.AddComponentFetcher<PersonaPage, PersonaPageComponentFetcher>();
builder.Services.AddComponentFetcher<CompetenceProfile, CompetenceProfileComponentFetcher>();
builder.Services.AddComponentFetcher<KpiMatrixCollection, KpiMatrixComponentFetcher>();

builder.Services.AddScoped<ICompetenceComponentService, CompetenceComponentService>(static (services) => new CompetenceComponentService(
new Dictionary<string, ICompetenceComponentFetcher>
{
{ "persona_page", services.GetRequiredService<ICompetenceComponentFetcher<PersonaPage>>() },
{ "competence_profile", services.GetRequiredService<ICompetenceComponentFetcher<CompetenceProfile>>() },
{ "kpi_matrix", services.GetRequiredService<ICompetenceComponentFetcher<KpiMatrixCollection>>() },
}
));
var app = builder.Build();

// Configure the HTTP request pipeline.
Expand Down
24 changes: 4 additions & 20 deletions Epsilon/Component/CompetenceProfileComponentFetcher.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Epsilon.Abstractions.Component;
using Epsilon.Abstractions.Component;
using Epsilon.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Model.GraphQl;
using Epsilon.Canvas.Abstractions.Service;
using Microsoft.Extensions.Configuration;
Expand Down Expand Up @@ -42,16 +41,13 @@ query MyQuery {

private readonly IConfiguration _configuration;
private readonly IGraphQlHttpService _graphQlService;
private readonly IAccountHttpService _accountHttpService;

public CompetenceProfileComponentFetcher(
IGraphQlHttpService graphQlService,
IAccountHttpService accountHttpService,
IConfiguration configuration
)
{
_graphQlService = graphQlService;
_accountHttpService = accountHttpService;
_configuration = configuration;
}

Expand All @@ -61,17 +57,15 @@ public override async Task<CompetenceProfile> Fetch(DateTime startDate, DateTime
var outcomesQuery = GetAllUserCoursesSubmissionOutcomes.Replace("$studentIds", $"{studentId}", StringComparison.InvariantCulture);

var outcomes = await _graphQlService.Query<CanvasGraphQlQueryResponse>(outcomesQuery);
var terms = await _accountHttpService.GetAllTerms(1);

var competenceProfile = ConvertToComponent(outcomes, new HboIDomain2018(), terms);
var competenceProfile = ConvertToComponent(outcomes, new HboIDomain2018());

return competenceProfile;
}

private static CompetenceProfile ConvertToComponent(
CanvasGraphQlQueryResponse queryResponse,
IHboIDomain domain,
IEnumerable<EnrollmentTerm> enrollmentTerms
IHboIDomain domain
)
{
var taskResults = new List<ProfessionalTaskResult>();
Expand Down Expand Up @@ -125,20 +119,10 @@ IEnumerable<EnrollmentTerm> enrollmentTerms
}
}

var filteredTerms = enrollmentTerms
.Where(static term => term is { StartAt: not null, EndAt: not null, })
.Where(term => taskResults.Any(taskOutcome =>
taskOutcome.AssessedAt >= term.StartAt && taskOutcome.AssessedAt <= term.EndAt)
|| professionalResults.Any(skillOutcome =>
skillOutcome.AssessedAt > term.StartAt && skillOutcome.AssessedAt < term.EndAt))
.Distinct()
.OrderByDescending(static term => term.StartAt);

return new CompetenceProfile(
domain,
taskResults.OrderByDescending(static r => r.SubmittedAt),
professionalResults.OrderByDescending(static r => r.SubmittedAt),
filteredTerms
professionalResults.OrderByDescending(static r => r.SubmittedAt)
);
}
}
23 changes: 7 additions & 16 deletions Epsilon/Service/CompetenceComponentService.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
using System.Reflection;
using Epsilon.Abstractions.Component;
using Epsilon.Abstractions.Service;

namespace Epsilon.Service;

public class CompetenceComponentService : ICompetenceComponentService
{
private readonly IEnumerable<ICompetenceComponentFetcher> _componentFetchers;
private readonly IDictionary<string, ICompetenceComponentFetcher> _componentFetchers;

public CompetenceComponentService(IEnumerable<ICompetenceComponentFetcher> componentFetchers)
public CompetenceComponentService(IDictionary<string, ICompetenceComponentFetcher> componentFetchers)
{
_componentFetchers = componentFetchers;
}

public async IAsyncEnumerable<ICompetenceComponent> GetComponents(DateTime startDate, DateTime endDate)
{
foreach (var componentFetcher in _componentFetchers)
foreach (var componentFetcher in _componentFetchers.Values)
{
yield return await componentFetcher.FetchUnknown(startDate, endDate);
}
Expand All @@ -34,20 +33,12 @@ public async IAsyncEnumerable<TComponent> GetComponents<TComponent>(DateTime sta

public async Task<ICompetenceComponent?> GetComponent(string name, DateTime startDate, DateTime endDate)
{
var fetcher = _componentFetchers.SingleOrDefault(f =>
if (_componentFetchers.TryGetValue(name, out var fetcher))
{
var componentType = f.GetType().BaseType?.GetGenericArguments()[0];
if (componentType != null)
{
var componentNameAttribute = componentType.GetCustomAttribute<CompetenceComponentNameAttribute>(false);
return componentNameAttribute?.Name == name;
}
return await fetcher.FetchUnknown(startDate, endDate);
}

return false;
});
return fetcher == null
? null
: await fetcher.FetchUnknown(startDate, endDate);
return null;
}

public async Task<TComponent?> GetComponent<TComponent>(string name, DateTime startDate, DateTime endDate) where TComponent : class, ICompetenceComponent
Expand Down
2 changes: 1 addition & 1 deletion Epsilon/Service/CompetenceDocumentService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public async Task<Stream> WriteDocument(Stream stream, DateTime startDate, DateT
{
var startPosition = stream.Position;

var components = await _competenceComponentService.GetComponents<ICompetenceWordComponent>(startDate, endDate).ToListAsync();
var components = await _competenceComponentService.GetComponents<IWordCompetenceComponent>(startDate, endDate).ToListAsync();
using var document = WordprocessingDocument.Create(stream, WordprocessingDocumentType.Document);

document.AddMainDocumentPart();
Expand Down
Loading

0 comments on commit c8e3a9c

Please sign in to comment.