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

Commit

Permalink
Add support for component based documents (EpsilonComponents) (#89)
Browse files Browse the repository at this point in the history
* Initial component architecture for JSON and Word export

* Added architecture for single point of component data retrieval and Word convertion

* Typo

* Cleanup component architecture and modify Word export to return OpenXML

* Add coding guidelines enforcement (#85)

* Add initial coding guidelines and fix where necessary

* Enforce code styling and update code where necessary

* Remove duplicate .editorconfig entries

* Add code analysis setup to CI

* Add missing checkout step

* Update incorrect action version tag

* Remove incompatible analysis step

* Push code style offense to validate CI pipeline

* Remove code style violation

* Add global.json

* Add support for dynamic component converters

* Removed Word component merging logic from controller to WordDownloader class

* Remve redundant method

* Remove accidental document

* Remove redundant models and interfaces

* Fix persona images not being added as Base64 (#84)

* Made some adjustments that the pictures in the persona get converted to Base64 strings versus loading it remotely from Canvas (as the access key is only valid for a limited time period)

* Add coding guidelines enforcement (#85)

* Add initial coding guidelines and fix where necessary

* Enforce code styling and update code where necessary

* Remove duplicate .editorconfig entries

* Add code analysis setup to CI

* Add missing checkout step

* Update incorrect action version tag

* Remove incompatible analysis step

* Push code style offense to validate CI pipeline

* Remove code style violation

* Add global.json

* Made a couple of changes based on recommendations made in the merge request.

---------

Co-authored-by: Jelle Maas <typiqally@gmail.com>

* Fix exporters no longer working correctly (#88)

* Temporarily fix paginator not working correctly

* Set format names to uppercase

* Fix stream being disposed before usage

* Fix homepage returning null when no images are present

* Cleanup Word downloader

* Change CLI project namespace to allow for additional projects

* Add initial Web API project

* Create controllers and endpoints

* Transform abstract class to interface

* Change classes to records & add poc endpoints

* Add download Word file endpoint

* Typo

* Add initial frontend code

* Add competence profile data model (#76)

* Initial proof of concept for competence profile data model

* Refactor competence profile return type

* Created endpoint with updated HboIDomain and Mockdata. Also created GraphQL endpoint for student data

* Cleanup records to seperate GraphQL folder

* Fix GraphQL records

---------

Co-authored-by: Jelle Maas <typiqally@gmail.com>
Co-authored-by: Sven Hansen <76601644+1SvenHansen@users.noreply.github.com>

* Link submission query with competence profile endpoint (#79)

* Added Professional development

* Rename namespace to correspond with coding guidelines

* Separate records into different files

* Rename Value to Name to correspond with domain

* Rename Value to Level to correspond with domain

* Add professional skills to domain

* Add short name to architectural layer and professional skills

* Rename properties in competence profile random data filler

* Rename CompetenceProfileOutcome to ProfessionalTaskOutcome

* Add Professional skill outcome to competence profile

* Use singular name

* Use id references instead of name values

* Use type keyword

* Add submissions from all courses from student to competence profile transformation

* Fix merge issues

* Add task and skill outcomes to competence profile return type

* Fetch terms from canvas

* Remove redundant imports

* Change default application url

* Prevent browser from launching on every restart

* Cleanup code

* Add filter enrolment term function

* Add terms to competence profile

* Remove unused terms function

* Added filter on professional outcomes and sorting

* Removed unused things

* V0.1

* Defining colors for elements

* Remove obsolete styling

* Update pnpm lock file

* Add Vue router

* Resolve ESLint warnings

* Add authorization view and controller

* Use controller templating for route

* A lot of stuff

* A lot of stuff

* Working

* Set it all to vue 3 supported format

* Fix import path

* Add CORS policy

* Realtime user data

* Add terms to competence profile

* Cleanup code and improve competence profile converter

* Filter on PostedAt value

---------

Co-authored-by: Tara <tarawillink@gmail.com>
Co-authored-by: Sven <svenroermond@hotmail.com>
Co-authored-by: Neal Geilen <info@nealgeilen.nl>

* Add performance dashboard frontend interface (#81)

* Added Professional development

* Rename namespace to correspond with coding guidelines

* Separate records into different files

* Rename Value to Name to correspond with domain

* Rename Value to Level to correspond with domain

* Add professional skills to domain

* Add short name to architectural layer and professional skills

* Rename properties in competence profile random data filler

* Rename CompetenceProfileOutcome to ProfessionalTaskOutcome

* Add Professional skill outcome to competence profile

* Use singular name

* Use id references instead of name values

* Use type keyword

* Add submissions from all courses from student to competence profile transformation

* Fix merge issues

* Add task and skill outcomes to competence profile return type

* Fetch terms from canvas

* Remove redundant imports

* Change default application url

* Prevent browser from launching on every restart

* Cleanup code

* V0.1

* Defining colors for elements

* Remove obsolete styling

* Update pnpm lock file

* Add Vue router

* Resolve ESLint warnings

* Add authorization view and controller

* Use controller templating for route

* A lot of stuff

* A lot of stuff

* Working

* Set it all to vue 3 supported format

* Fix import path

* Add CORS policy

* Realtime user data

* Bugfixes

* Add filter enrolment term function

* Add terms to competence profile

* Remove unused terms function

* Added filter on professional outcomes and sorting

* Removed unused things

* Realtime user data

* Add terms to competence profile

* Cleanup code and improve competence profile converter

* Filter on PostedAt value

* Added frontend grid & colors

---------

Co-authored-by: Tara <tarawillink@gmail.com>
Co-authored-by: Jelle Maas <typiqally@gmail.com>
Co-authored-by: Sven <svenroermond@hotmail.com>
Co-authored-by: Eline <elinevooijs@outlook.com>

* Add decaying average calculations (#80)

* initial version of the decaying average functionality

* Added Professional development

* Rename namespace to correspond with coding guidelines

* Separate records into different files

* Rename Value to Name to correspond with domain

* Rename Value to Level to correspond with domain

* Add professional skills to domain

* Add short name to architectural layer and professional skills

* Rename properties in competence profile random data filler

* Rename CompetenceProfileOutcome to ProfessionalTaskOutcome

* Add Professional skill outcome to competence profile

* Use singular name

* Use id references instead of name values

* Use type keyword

* re-adding decaying average files and logic

* Add submissions from all courses from student to competence profile transformation

* Fix merge issues

* Add task and skill outcomes to competence profile return type

* Fetch terms from canvas

* Remove redundant imports

* Change default application url

* Prevent browser from launching on every restart

* Cleanup code

* Add filter enrolment term function

* Add terms to competence profile

* Remove unused terms function

* Added filter on professional outcomes and sorting

* Removed unused things

* V0.1

* Defining colors for elements

* Remove obsolete styling

* Update pnpm lock file

* Add Vue router

* Resolve ESLint warnings

* Add authorization view and controller

* Use controller templating for route

* A lot of stuff

* A lot of stuff

* Working

* Set it all to vue 3 supported format

* Fix import path

* Add CORS policy

* Realtime user data

* Add terms to competence profile

* Cleanup code and improve competence profile converter

* Filter on PostedAt value

* initial version of the decaying average functionality

* re-adding decaying average files and logic

* Decaying average calculation functionality supporting both ArchitectureLayer and Skill outcomes

* Decaying average calculation functional per layer per activity and skills are independent of layers

---------

Co-authored-by: jan.fojtik <jan.fojtik@indicia.nl>
Co-authored-by: Tara <tarawillink@gmail.com>
Co-authored-by: Jelle Maas <typiqally@gmail.com>
Co-authored-by: Sven <svenroermond@hotmail.com>
Co-authored-by: Neal Geilen <info@nealgeilen.nl>

* Fix to not all learning outcomes getting retrieved (#82)

* Attempt to fix not all learning outcomes getting retrieved

* Use submission histories instead of rubric assessments directly

* Ensure rubric assessments nodes has elements

* Add performance dashboard frontend interface (#81)

* Added Professional development

* Rename namespace to correspond with coding guidelines

* Separate records into different files

* Rename Value to Name to correspond with domain

* Rename Value to Level to correspond with domain

* Add professional skills to domain

* Add short name to architectural layer and professional skills

* Rename properties in competence profile random data filler

* Rename CompetenceProfileOutcome to ProfessionalTaskOutcome

* Add Professional skill outcome to competence profile

* Use singular name

* Use id references instead of name values

* Use type keyword

* Add submissions from all courses from student to competence profile transformation

* Fix merge issues

* Add task and skill outcomes to competence profile return type

* Fetch terms from canvas

* Remove redundant imports

* Change default application url

* Prevent browser from launching on every restart

* Cleanup code

* V0.1

* Defining colors for elements

* Remove obsolete styling

* Update pnpm lock file

* Add Vue router

* Resolve ESLint warnings

* Add authorization view and controller

* Use controller templating for route

* A lot of stuff

* A lot of stuff

* Working

* Set it all to vue 3 supported format

* Fix import path

* Add CORS policy

* Realtime user data

* Bugfixes

* Add filter enrolment term function

* Add terms to competence profile

* Remove unused terms function

* Added filter on professional outcomes and sorting

* Removed unused things

* Realtime user data

* Add terms to competence profile

* Cleanup code and improve competence profile converter

* Filter on PostedAt value

* Added frontend grid & colors

---------

Co-authored-by: Tara <tarawillink@gmail.com>
Co-authored-by: Jelle Maas <typiqally@gmail.com>
Co-authored-by: Sven <svenroermond@hotmail.com>
Co-authored-by: Eline <elinevooijs@outlook.com>

* Add decaying average calculations (#80)

* initial version of the decaying average functionality

* Added Professional development

* Rename namespace to correspond with coding guidelines

* Separate records into different files

* Rename Value to Name to correspond with domain

* Rename Value to Level to correspond with domain

* Add professional skills to domain

* Add short name to architectural layer and professional skills

* Rename properties in competence profile random data filler

* Rename CompetenceProfileOutcome to ProfessionalTaskOutcome

* Add Professional skill outcome to competence profile

* Use singular name

* Use id references instead of name values

* Use type keyword

* re-adding decaying average files and logic

* Add submissions from all courses from student to competence profile transformation

* Fix merge issues

* Add task and skill outcomes to competence profile return type

* Fetch terms from canvas

* Remove redundant imports

* Change default application url

* Prevent browser from launching on every restart

* Cleanup code

* Add filter enrolment term function

* Add terms to competence profile

* Remove unused terms function

* Added filter on professional outcomes and sorting

* Removed unused things

* V0.1

* Defining colors for elements

* Remove obsolete styling

* Update pnpm lock file

* Add Vue router

* Resolve ESLint warnings

* Add authorization view and controller

* Use controller templating for route

* A lot of stuff

* A lot of stuff

* Working

* Set it all to vue 3 supported format

* Fix import path

* Add CORS policy

* Realtime user data

* Add terms to competence profile

* Cleanup code and improve competence profile converter

* Filter on PostedAt value

* initial version of the decaying average functionality

* re-adding decaying average files and logic

* Decaying average calculation functionality supporting both ArchitectureLayer and Skill outcomes

* Decaying average calculation functional per layer per activity and skills are independent of layers

---------

Co-authored-by: jan.fojtik <jan.fojtik@indicia.nl>
Co-authored-by: Tara <tarawillink@gmail.com>
Co-authored-by: Jelle Maas <typiqally@gmail.com>
Co-authored-by: Sven <svenroermond@hotmail.com>
Co-authored-by: Neal Geilen <info@nealgeilen.nl>

* Correct HBO-i domain layer order

* Add performance dashboard frontend interface (#81)

* Added Professional development

* Rename namespace to correspond with coding guidelines

* Separate records into different files

* Rename Value to Name to correspond with domain

* Rename Value to Level to correspond with domain

* Add professional skills to domain

* Add short name to architectural layer and professional skills

* Rename properties in competence profile random data filler

* Rename CompetenceProfileOutcome to ProfessionalTaskOutcome

* Add Professional skill outcome to competence profile

* Use singular name

* Use id references instead of name values

* Use type keyword

* Add submissions from all courses from student to competence profile transformation

* Fix merge issues

* Add task and skill outcomes to competence profile return type

* Fetch terms from canvas

* Remove redundant imports

* Change default application url

* Prevent browser from launching on every restart

* Cleanup code

* V0.1

* Defining colors for elements

* Remove obsolete styling

* Update pnpm lock file

* Add Vue router

* Resolve ESLint warnings

* Add authorization view and controller

* Use controller templating for route

* A lot of stuff

* A lot of stuff

* Working

* Set it all to vue 3 supported format

* Fix import path

* Add CORS policy

* Realtime user data

* Bugfixes

* Add filter enrolment term function

* Add terms to competence profile

* Remove unused terms function

* Added filter on professional outcomes and sorting

* Removed unused things

* Realtime user data

* Add terms to competence profile

* Cleanup code and improve competence profile converter

* Filter on PostedAt value

* Added frontend grid & colors

---------

Co-authored-by: Tara <tarawillink@gmail.com>
Co-authored-by: Jelle Maas <typiqally@gmail.com>
Co-authored-by: Sven <svenroermond@hotmail.com>
Co-authored-by: Eline <elinevooijs@outlook.com>

* Add decaying average calculations (#80)

* initial version of the decaying average functionality

* Added Professional development

* Rename namespace to correspond with coding guidelines

* Separate records into different files

* Rename Value to Name to correspond with domain

* Rename Value to Level to correspond with domain

* Add professional skills to domain

* Add short name to architectural layer and professional skills

* Rename properties in competence profile random data filler

* Rename CompetenceProfileOutcome to ProfessionalTaskOutcome

* Add Professional skill outcome to competence profile

* Use singular name

* Use id references instead of name values

* Use type keyword

* re-adding decaying average files and logic

* Add submissions from all courses from student to competence profile transformation

* Fix merge issues

* Add task and skill outcomes to competence profile return type

* Fetch terms from canvas

* Remove redundant imports

* Change default application url

* Prevent browser from launching on every restart

* Cleanup code

* Add filter enrolment term function

* Add terms to competence profile

* Remove unused terms function

* Added filter on professional outcomes and sorting

* Removed unused things

* V0.1

* Defining colors for elements

* Remove obsolete styling

* Update pnpm lock file

* Add Vue router

* Resolve ESLint warnings

* Add authorization view and controller

* Use controller templating for route

* A lot of stuff

* A lot of stuff

* Working

* Set it all to vue 3 supported format

* Fix import path

* Add CORS policy

* Realtime user data

* Add terms to competence profile

* Cleanup code and improve competence profile converter

* Filter on PostedAt value

* initial version of the decaying average functionality

* re-adding decaying average files and logic

* Decaying average calculation functionality supporting both ArchitectureLayer and Skill outcomes

* Decaying average calculation functional per layer per activity and skills are independent of layers

---------

Co-authored-by: jan.fojtik <jan.fojtik@indicia.nl>
Co-authored-by: Tara <tarawillink@gmail.com>
Co-authored-by: Jelle Maas <typiqally@gmail.com>
Co-authored-by: Sven <svenroermond@hotmail.com>
Co-authored-by: Neal Geilen <info@nealgeilen.nl>

* Attempt to fix not all learning outcomes getting retrieved

* Use submission histories instead of rubric assessments directly

* Ensure rubric assessments nodes has elements

* Correct HBO-i domain layer order

---------

Co-authored-by: Jelle Maas <typiqally@gmail.com>
Co-authored-by: Tara <tarawillink@gmail.com>
Co-authored-by: Sven <svenroermond@hotmail.com>
Co-authored-by: Eline <elinevooijs@outlook.com>
Co-authored-by: jendafojtik <83012368+jendafojtik@users.noreply.github.com>
Co-authored-by: jan.fojtik <jan.fojtik@indicia.nl>

* Initial component architecture for JSON and Word export

* Added architecture for single point of component data retrieval and Word convertion

* Typo

* Cleanup component architecture and modify Word export to return OpenXML

* Add support for dynamic component converters

* Removed Word component merging logic from controller to WordDownloader class

* Remve redundant method

* Remove accidental document

* Remove redundant models and interfaces

* Cleanup Word downloader

* Fix code analysis issues

* Fix incorrect interface reference

* Remove CLI projects and its dependencies

* Rename Epsilon component classes

* Reformat records

* Remove obsolete test

* Rename TResponse to TComponent

* Remove redundant export data

* Remove redundant interface

* Add service collection extensions for components

* Rework component converters to be included in component models

* Move domain logic in controller to separate services

* Move component name to attribute and rename to competence component

* Remove duplicate package reference

* Move HttpService class to Canvas project

* Remove unused constants

* Modify persona page to accommodate new component architecture (#91)

* Created PersonaPage component for the new architecture.

* fix feedback sven

* Cleanup code

* Modify architecture to force adding Word components instead of creating them

* Add using statement to ensure stream is disposed

---------

Co-authored-by: Jelle Maas <typiqally@gmail.com>

* Add initial KPI matrix component (#87)

* Created KpiMatrix component

* Added modules and fixed comments

* Fixed an issue where outcomes where duplicate

* Created KPIMatrix in word document

* Fixed all remaining issues.

* Merge conflicts

* Fixed MR requests

* Changed course to allcourses

* File restructure

* Revised coding structure. Assignments that are not yest graded are also now included

* Merged files in new structure

* Colored rows

* "Simplified"

* Move HttpService class to Canvas project

* Added legend and changed "GradeStatus" structure

* Remove unused constants

* Modify persona page to accommodate new component architecture (#91)

* Created PersonaPage component for the new architecture.

* fix feedback sven

* Cleanup code

* Modify architecture to force adding Word components instead of creating them

* Add using statement to ensure stream is disposed

---------

Co-authored-by: Jelle Maas <typiqally@gmail.com>

* Move HttpService class to Canvas project

* Remove unused constants

* Modify persona page to accommodate new component architecture (#91)

* Created PersonaPage component for the new architecture.

* fix feedback sven

* Cleanup code

* Modify architecture to force adding Word components instead of creating them

* Add using statement to ensure stream is disposed

---------

Co-authored-by: Jelle Maas <typiqally@gmail.com>

* Created KpiMatrix component

* Added modules and fixed comments

* Merge conflicts

* File restructure

* Revised coding structure. Assignments that are not yest graded are also now included

* Created KpiMatrix component

* Added modules and fixed comments

* Merge conflicts

* File restructure

* Revised coding structure. Assignments that are not yest graded are also now included

* Added legend and changed "GradeStatus" structure

* Added extra grade type

* Added legend to json result

* Working order

* startDate & endDate implementation for document generator

* POC working

* Created KpiMatrix component

* Added modules and fixed comments

* Fixed an issue where outcomes where duplicate

* Created KPIMatrix in word document

* Fixed all remaining issues.

* Merge conflicts

* Fixed MR requests

* Changed course to allcourses

* File restructure

* Revised coding structure. Assignments that are not yest graded are also now included

* Merged files in new structure

* Colored rows

* "Simplified"

* Added legend and changed "GradeStatus" structure

* Created KpiMatrix component

* Added modules and fixed comments

* Merge conflicts

* File restructure

* Revised coding structure. Assignments that are not yest graded are also now included

* Created KpiMatrix component

* Added modules and fixed comments

* Merge conflicts

* File restructure

* Revised coding structure. Assignments that are not yest graded are also now included

* Added legend and changed "GradeStatus" structure

* Added extra grade type

* Added legend to json result

* Working order

* startDate & endDate implementation for document generator

* POC working

* changes

* Lint fixes

* Lint fixes

* Cleanup code and update coding guidelines

* Change outcome grade statuses

* Cleanup code

---------

Co-authored-by: Neal Geilen <info@nealgeilen.nl>
Co-authored-by: Jelle Maas <typiqally@gmail.com>
Co-authored-by: Koen Janssen <6256259+koen253janssen@users.noreply.github.com>

---------

Co-authored-by: Sven <svenroermond@hotmail.com>
Co-authored-by: Koen Janssen <6256259+koen253janssen@users.noreply.github.com>
Co-authored-by: Sven Hansen <76601644+1SvenHansen@users.noreply.github.com>
Co-authored-by: Sven Hansen <76601644+SyntaxSven@users.noreply.github.com>
Co-authored-by: Tara <tarawillink@gmail.com>
Co-authored-by: Neal Geilen <info@nealgeilen.nl>
Co-authored-by: Eline <elinevooijs@outlook.com>
Co-authored-by: jendafojtik <83012368+jendafojtik@users.noreply.github.com>
Co-authored-by: jan.fojtik <jan.fojtik@indicia.nl>
Co-authored-by: Jasper123pyah <73039915+Jasper123pyah@users.noreply.github.com>
  • Loading branch information
11 people authored May 26, 2023
1 parent f2381f0 commit 33c6a87
Show file tree
Hide file tree
Showing 130 changed files with 2,544 additions and 2,870 deletions.
529 changes: 529 additions & 0 deletions .editorconfig

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2

- name: Setup .NET
uses: actions/setup-dotnet@v1.7.2
with:
Expand All @@ -25,7 +25,7 @@ jobs:

- name: Build
run: dotnet build --no-restore

test:
name: Test
needs: [ setup, build ]
Expand Down
8 changes: 8 additions & 0 deletions Epsilon.Abstractions/Component/CompetenceComponentFetcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Epsilon.Abstractions.Component;

public abstract class CompetenceComponentFetcher<TComponent> : ICompetenceComponentFetcher<TComponent> where TComponent : ICompetenceComponent
{
public async Task<ICompetenceComponent> FetchUnknown(DateTime startDate, DateTime endDate) => await Fetch(startDate, endDate);

public abstract Task<TComponent> Fetch(DateTime startDate, DateTime endDate);
}
12 changes: 12 additions & 0 deletions Epsilon.Abstractions/Component/CompetenceComponentNameAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Epsilon.Abstractions.Component;

[AttributeUsage(AttributeTargets.Class)]
public sealed class CompetenceComponentNameAttribute : Attribute
{
public CompetenceComponentNameAttribute(string name)
{
Name = name;
}

public string Name { get; }
}
36 changes: 36 additions & 0 deletions Epsilon.Abstractions/Component/CompetenceProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using Epsilon.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Model;

namespace Epsilon.Abstractions.Component;

[CompetenceComponentName("competence_profile")]
public record CompetenceProfile(
IHboIDomain HboIDomain,
IEnumerable<ProfessionalTaskResult> ProfessionalTaskOutcomes,
IEnumerable<ProfessionalSkillResult> ProfessionalSkillOutcomes,
IEnumerable<EnrollmentTerm> Terms,
IEnumerable<DecayingAveragePerLayer> DecayingAveragesPerTask,
IEnumerable<DecayingAveragePerSkill> DecayingAveragesPerSkill
) : ICompetenceWordComponent
{
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)
)
)
);
}

mainDocumentPart.Document.AppendChild(body);
}
}
8 changes: 8 additions & 0 deletions Epsilon.Abstractions/Component/ICompetenceComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Epsilon.Abstractions.Component;

#pragma warning disable CA1040
public interface ICompetenceComponent
#pragma warning restore CA1040
{

}
12 changes: 12 additions & 0 deletions Epsilon.Abstractions/Component/ICompetenceComponentFetcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Epsilon.Abstractions.Component;

public interface ICompetenceComponentFetcher
{
public Task<ICompetenceComponent> FetchUnknown(DateTime startDate, DateTime endDate);
}

public interface ICompetenceComponentFetcher<TComponent> : ICompetenceComponentFetcher
where TComponent : ICompetenceComponent
{
public Task<TComponent> Fetch(DateTime startDate, DateTime endDate);
}
11 changes: 0 additions & 11 deletions Epsilon.Abstractions/Component/ICompetenceProfileConverter.cs

This file was deleted.

8 changes: 8 additions & 0 deletions Epsilon.Abstractions/Component/ICompetenceWordComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using DocumentFormat.OpenXml.Packaging;

namespace Epsilon.Abstractions.Component;

public interface ICompetenceWordComponent : ICompetenceComponent
{
public void AddToWordDocument(MainDocumentPart mainDocumentPart);
}
6 changes: 6 additions & 0 deletions Epsilon.Abstractions/Component/KpiMatrixAssignment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Epsilon.Abstractions.Component;

public record KpiMatrixAssignment(
string Name,
IEnumerable<KpiMatrixOutcome> Outcomes
);
196 changes: 196 additions & 0 deletions Epsilon.Abstractions/Component/KpiMatrixCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using Epsilon.Canvas.Abstractions.Model;

namespace Epsilon.Abstractions.Component;

[CompetenceComponentName("kpi_matrix")]
public record KpiMatrixCollection(
IEnumerable<KpiMatrixAssignment> KpiMatrixAssignments,
IDictionary<OutcomeGradeStatus, KpiMatrixOutcomeGradeStatus> GradeStatus
) : ICompetenceWordComponent
{
public static readonly IDictionary<OutcomeGradeStatus, KpiMatrixOutcomeGradeStatus> DefaultGradeStatus = new Dictionary<OutcomeGradeStatus, KpiMatrixOutcomeGradeStatus>
{
{
OutcomeGradeStatus.Mastered, new KpiMatrixOutcomeGradeStatus("Mastered", "44F656")
},
{
OutcomeGradeStatus.NotMastered, new KpiMatrixOutcomeGradeStatus("Insufficient", "FA1818")
},
{
OutcomeGradeStatus.NotGraded, new KpiMatrixOutcomeGradeStatus("Not applicable", "FAFF00")
},
{
OutcomeGradeStatus.NotAssessed, new KpiMatrixOutcomeGradeStatus("Needs grade", "9F2B68")
},
};

public void AddToWordDocument(MainDocumentPart mainDocumentPart)
{
var body = new Body();
// Create a table, with rows for the outcomes and columns for the assignments.
var table = new Table();

var assignments = KpiMatrixAssignments.OrderBy(static ass => ass.Name).ToList();

// Set table properties for formatting.
table.AppendChild(new TableProperties(
new TableWidth
{
Width = "0", Type = TableWidthUnitValues.Auto,
}));

// Calculate the header row height based on the longest assignment name.
var headerRowHeight = 0;
if (KpiMatrixAssignments.Any())
{
headerRowHeight = assignments.Max(static a => a.Name.Length) * 111;
}

// Create the table header row.
var headerRow = new TableRow();
headerRow.AppendChild(new TableRowProperties(new TableRowHeight
{
Val = (UInt32Value)(uint)headerRowHeight,
}));

// Empty top-left cell.
headerRow.AppendChild(CreateTableCellWithBorders("2500", new Paragraph(new Run(new Text("")))));

foreach (var assignment in assignments)
{
var cell = CreateTableCellWithBorders("100");
cell.FirstChild.Append(new TextDirection
{
Val = TextDirectionValues.TopToBottomLeftToRightRotated,
});

cell.Append(new Paragraph(new Run(new Text(assignment.Name))));
cell.FirstChild.Append(new Shading
{
Fill = assignments.IndexOf(assignment) % 2 == 0
? "FFFFFF"
: "d3d3d3",
});
headerRow.AppendChild(cell);
}

table.AppendChild(headerRow);

var listOfOutcomes = new Dictionary<int, KpiMatrixOutcome>();
foreach (var assignment in KpiMatrixAssignments)
{
foreach (var outcome in assignment.Outcomes)
{
listOfOutcomes.TryAdd(outcome.Id, outcome);
}
}

// Add the outcome rows.
foreach (var outcome in listOfOutcomes.OrderByDescending(static o => o.Value.Title))
{
var row = new TableRow();

// Add the outcome title cell.
row.AppendChild(CreateTableCellWithBorders("2500", new Paragraph(new Run(new Text(outcome.Value.Title)))));

// Add the assignment cells.
foreach (var assignment in assignments)
{
var outcomeAssignment = assignment.Outcomes.FirstOrDefault(o => o.Id == outcome.Key);
var cell = CreateTableCellWithBorders("100");

// Set cell color based on GradeStatus.
var fillColor = outcomeAssignment != null
? outcomeAssignment.GradeStatus.Color
: assignments.IndexOf(assignment) % 2 == 0
? "ffffff"
: "d3d3d3";

cell.FirstChild?.Append(new Shading
{
Fill = fillColor,
});

// Add an empty text element since we're using color instead of text.
cell.Append(new Paragraph(new Run(new Text(""))));
row.AppendChild(cell);
}

table.AppendChild(row);
}

body.AppendChild(GetLegend());
body.Append(new Paragraph(new Run(new Text(""))));
body.AppendChild(table);

mainDocumentPart.Document.AppendChild(body);
}

private OpenXmlElement GetLegend()
{
var table = new Table();
foreach (var status in GradeStatus)
{
var row = new TableRow();
var cellName = CreateTableCellWithBorders("200");
cellName.Append(new Paragraph(new Run(new Text(status.Value.Status))));

var cellValue = CreateTableCellWithBorders("200");
cellValue.Append(new Paragraph(new Run(new Text(""))));
cellValue.FirstChild?.Append(new Shading
{
Fill = status.Value.Color,
});
row.AppendChild(cellName);
row.AppendChild(cellValue);
table.AppendChild(row);
}

return table;
}


private static TableCell CreateTableCellWithBorders(string? width, params OpenXmlElement[] elements)
{
var cell = new TableCell();
var cellProperties = new TableCellProperties();
var borders = new TableCellBorders(
new LeftBorder
{
Val = BorderValues.Single,
},
new RightBorder
{
Val = BorderValues.Single,
},
new TopBorder
{
Val = BorderValues.Single,
},
new BottomBorder
{
Val = BorderValues.Single,
});

foreach (var element in elements)
{
cell.Append(element);
}

if (width != null)
{
cellProperties.Append(new TableCellWidth
{
Type = TableWidthUnitValues.Dxa, Width = width,
});
}

cellProperties.Append(borders);
cell.PrependChild(cellProperties);

return cell;
}
}
7 changes: 7 additions & 0 deletions Epsilon.Abstractions/Component/KpiMatrixOutcome.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

namespace Epsilon.Abstractions.Component;
public record KpiMatrixOutcome(
int Id,
string Title,
KpiMatrixOutcomeGradeStatus GradeStatus
);
6 changes: 6 additions & 0 deletions Epsilon.Abstractions/Component/KpiMatrixOutcomeGradeStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Epsilon.Abstractions.Component;

public record KpiMatrixOutcomeGradeStatus(
string Status,
string Color
);
25 changes: 25 additions & 0 deletions Epsilon.Abstractions/Component/PersonaPage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Text;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

namespace Epsilon.Abstractions.Component;

[CompetenceComponentName("persona")]
public record PersonaPage(string PersonaHtml) : ICompetenceWordComponent
{
public void AddToWordDocument(MainDocumentPart mainDocumentPart)
{
var personaHtmlBuffer = Encoding.UTF8.GetPreamble().Concat(Encoding.UTF8.GetBytes($"<html>{PersonaHtml}</html>")).ToArray();
using var personaHtmlStream = new MemoryStream(personaHtmlBuffer);

var formatImportPart = mainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Html);
formatImportPart.FeedData(personaHtmlStream);

mainDocumentPart.Document.AppendChild(new Body(
new AltChunk
{
Id = mainDocumentPart.GetIdOfPart(formatImportPart),
}
));
}
}
Loading

0 comments on commit 33c6a87

Please sign in to comment.