Skip to content

Commit 35b44e9

Browse files
committed
fix: merge and Api key generation
1 parent 7eae16c commit 35b44e9

File tree

13 files changed

+1008
-80
lines changed

13 files changed

+1008
-80
lines changed

grade-management-new/GradeManagement.Client/Components/NewDialogs/NewExerciseDialog.razor

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
<MudForm @ref="form" Model="@value" @bind-IsValid="@success" @bind-Errors="@errors">
77
<MudTextField T="string" Label="Name" For="@(() => value.Name)" @bind-Value="value.Name" Required="true"></MudTextField>
88
<MudTextField T="string" Label="Github Prefix" For="@(() => value.GithubPrefix)" @bind-Value="value.GithubPrefix" Required="true"></MudTextField>
9+
@* <MudTextField T="string" Label="Github Prefix" For="@(() => value.DueDate)" @bind-Value="value.DueDate" Required="true"></MudTextField> *@
10+
@* <MudTextField T="string" Label="Github Prefix" For="@(() => value.ScoreTypes)" @bind-Value="value.ScoreTypes" Required="true"></MudTextField> *@
911
</MudForm>
1012
</DialogContent>
1113
<DialogActions>
@@ -33,6 +35,10 @@
3335
}
3436
}
3537

36-
public ExerciseRequest value = new();
38+
public ExerciseRequest value = new()
39+
{
40+
DueDate = DateTime.Now,
41+
ScoreTypes = new Dictionary<string, string>()
42+
};
3743

3844
}

grade-management-new/GradeManagement.Client/Components/NewDialogs/NewSubjectDialog.razor

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
<MudDialog>
1+
@inject CrudSnackbarService SnackbarService
2+
@inject CurrentUserService CurrentUserService
3+
4+
<MudDialog>
25
<TitleContent>
36
<MudText Typo="Typo.h4">New Subject</MudText>
47
</TitleContent>
@@ -7,6 +10,10 @@
710
<MudTextField T="string" Label="Name" For="@(() => value.Name)" @bind-Value="value.Name" Required="true"></MudTextField>
811
<MudTextField T="string" Label="Neptun Code" @bind-Value="value.NeptunCode" Required="true" Validation="@(new Func<string, IEnumerable<string>>(NeptunCodeValidator))"></MudTextField>
912
<MudTextField T="string" Label="Github Org" For="@(() => value.GitHubOrgName)" @bind-Value="value.GitHubOrgName" Required="true"></MudTextField>
13+
<div class="d-flex align-center">
14+
<MudTextField T="string" Label="API Key" For="@(() => value.CiApiKey)" @bind-Value="value.CiApiKey" Required="true" Class="flex-grow-1 me-2"></MudTextField>
15+
<MudIconButton Icon="@Icons.Material.Filled.Refresh" OnClick="GenerateApiKey" Size="Size.Small"/>
16+
</div>
1017
</MudForm>
1118
</DialogContent>
1219
<DialogActions>
@@ -25,11 +32,18 @@
2532
private void Submit() => MudDialog.Close(DialogResult.Ok(value));
2633
private void Cancel() => MudDialog.Cancel();
2734

35+
private void GenerateApiKey()
36+
{
37+
value.CiApiKey = Guid.NewGuid().ToString();
38+
SnackbarService.ShowMessage("Current user: " + CurrentUserService.User.Name);
39+
}
40+
2841
private async void OnSubmitClicked()
2942
{
3043
await form.Validate();
3144
if (form.IsValid)
3245
{
46+
value.Teachers.Add(CurrentUserService.User);
3347
Submit();
3448
}
3549
}

grade-management-new/GradeManagement.Client/Layout/MainComponent.razor

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
@inherits LayoutComponentBase
22
@inject SubjectService SubjectService
3+
@inject UserClient UserClient
4+
@inject CurrentUserService CurrentUserService
35

46
<LoadingComponent LongTask="@Init">
57
<ErrorBoundary @ref="errorBoundary">
@@ -36,6 +38,10 @@
3638
{
3739
Console.WriteLine("MainComponent Init");
3840
await SubjectService.LoadSubjects();
41+
if (CurrentUserService.User == null)
42+
{
43+
CurrentUserService.User = await UserClient.GetCurrentUserAsync();
44+
}
3945
}
4046

4147
}

grade-management-new/GradeManagement.Client/Network/NetworkManager.cs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,6 +1712,10 @@ public virtual async System.Threading.Tasks.Task<Course> CreateAsync(Course requ
17121712
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
17131713
}
17141714
}
1715+
catch (Exception ex)
1716+
{
1717+
throw new ApiException(ex.Message, 400, "responseData_", null, null);
1718+
}
17151719
finally
17161720
{
17171721
if (disposeResponse_)
@@ -7108,27 +7112,13 @@ public partial class CiEvaluationCompleted : AssignmentEventBase
71087112
public string StudentNeptun { get; set; }
71097113

71107114
[Newtonsoft.Json.JsonProperty("scores", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
7111-
public System.Collections.Generic.ICollection<EventScore> Scores { get; set; }
7115+
public System.Collections.Generic.IDictionary<string, double> Scores { get; set; }
71127116

71137117
[Newtonsoft.Json.JsonProperty("ciApiKey", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
71147118
public string CiApiKey { get; set; }
71157119

71167120
}
71177121

7118-
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")]
7119-
public partial class EventScore
7120-
{
7121-
[Newtonsoft.Json.JsonProperty("value", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
7122-
public long Value { get; set; }
7123-
7124-
[Newtonsoft.Json.JsonProperty("createdDate", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
7125-
public System.DateTimeOffset CreatedDate { get; set; }
7126-
7127-
[Newtonsoft.Json.JsonProperty("scoreType", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
7128-
public string ScoreType { get; set; }
7129-
7130-
}
7131-
71327122
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.7.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")]
71337123
public partial class TeacherAssigned : AssignmentEventBase
71347124
{
@@ -7150,7 +7140,7 @@ public partial class AssignmentGradedByTeacher : AssignmentEventBase
71507140
public string TeacherGitHubId { get; set; }
71517141

71527142
[Newtonsoft.Json.JsonProperty("scores", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
7153-
public System.Collections.Generic.ICollection<EventScore> Scores { get; set; }
7143+
public System.Collections.Generic.IDictionary<string, double> Scores { get; set; }
71547144

71557145
[Newtonsoft.Json.JsonProperty("dateOfGrading", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
71567146
public System.DateTimeOffset DateOfGrading { get; set; }

grade-management-new/GradeManagement.Client/Network/SubjectHeaderHandler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
namespace GradeManagement.Client.Network;
66

7-
public class SubjectHeaderHandler(SubjectService SubjectService) : DelegatingHandler
7+
public class SubjectHeaderHandler(SelectedSubjectService SelectedSubjectService) : DelegatingHandler
88
{
99
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
1010
CancellationToken cancellationToken)
1111
{
1212
Console.WriteLine("SubjectHeaderHandler");
13-
var subjectId = SubjectService.CurrentSubject?.Id;
13+
var subjectId = SelectedSubjectService.CurrentSubject?.Id;
1414
if (subjectId is not null)
1515
{
1616
request.Headers.Add("X-Subject-Id-Value", subjectId.ToString());

grade-management-new/GradeManagement.Client/Pages/Main.razor

Lines changed: 68 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
@page "/"
22
@using GradeManagement.Client.Components.NewDialogs
3+
@using MudExtensions
34
@layout AuthenticatedLayout
45

56
@inject SubjectService SubjectService
@@ -14,18 +15,18 @@
1415

1516
<style>
1617
.sort-direction-icon {
17-
--path-svg: 'M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'
18+
--path-svg: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'
1819
}
1920
20-
.sort-direction-icon.mud-direction-asc {
21-
--path-svg: 'M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'
21+
.sort-direction-icon.mud-direction-desc {
22+
--path-svg: 'M4.82 19 3.41 17.59l12-12L21 11.18l-1.42 1.41-4.17-4.17Z';
2223
}
2324
24-
.sort-direction-icon.mud-direction-desc {
25+
.sort-direction-icon.mud-direction-asc {
2526
--path-svg: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'
2627
}
2728
28-
.custom-grid .mud-table-cell .column-header .column-options .sort-direction-icon path {
29+
.custom-grid .mud-table-cell.pipa .column-header .column-options .sort-direction-icon path {
2930
d: path(var(--path-svg))
3031
}
3132
</style>
@@ -35,23 +36,19 @@
3536
<MudDivider Class="mb-4"/>
3637

3738
<MudStack Row="true" Class="mt-6">
38-
<MudSelect T="string" Label="Course" @bind-Value="_selectedCourse" @bind-Value:after="CourseChanged"
39-
Dense="true" Variant="Variant.Outlined" AnchorOrigin="Origin.BottomCenter"
40-
TransformOrigin="Origin.TopCenter">
41-
@foreach (var course in _courses ?? [])
39+
<MudSelectExtended ItemCollection="_courses?.ToList()" SearchBox="true" SelectAllPosition="SelectAllPosition.AfterSearchBox" SelectAll="true" MultiSelection="true" @bind-SelectedValues="_selectedCourse" @bind-SelectedValues:after="FilterChanged" T="string" Label="Course" AdornmentIcon="@Icons.Material.Filled.Search" AnchorOrigin="Origin.BottomCenter" Variant="Variant.Outlined">
40+
@foreach (var course in _courses)
4241
{
43-
<MudSelectItem Value="@course">@course</MudSelectItem>
42+
<MudSelectItemExtended T="string" Value="@course" Text="@course"/>
4443
}
45-
</MudSelect>
44+
</MudSelectExtended>
4645
<MudSpacer/>
47-
<MudSelect T="string" Label="Exercise" @bind-Value="_selectedExercise" @bind-Value:after="ExerciseChanged"
48-
Dense="true" Variant="Variant.Outlined" AnchorOrigin="Origin.BottomCenter"
49-
TransformOrigin="Origin.TopCenter">
50-
@foreach (var task in _tasks ?? [])
46+
<MudSelectExtended ItemCollection="_tasks?.ToList()" SearchBox="true" SelectAllPosition="SelectAllPosition.AfterSearchBox" SelectAll="true" MultiSelection="true" @bind-SelectedValues="_selectedExercise" @bind-SelectedValues:after="FilterChanged" T="string" Label="Exercise" AdornmentIcon="@Icons.Material.Filled.Search" AnchorOrigin="Origin.BottomCenter" Variant="Variant.Outlined">
47+
@foreach (var task in _tasks)
5148
{
52-
<MudSelectItem Value="@task">@task</MudSelectItem>
49+
<MudSelectItemExtended T="string" Value="@task" Text="@task"/>
5350
}
54-
</MudSelect>
51+
</MudSelectExtended>
5552
<MudSpacer/>
5653

5754
<MudIconButton Icon="@Icons.Material.Filled.Download" Color="Color.Inherit" Edge="Edge.End" Size="Size.Large"/>
@@ -60,15 +57,15 @@
6057
<Columns>
6158
<PropertyColumn Property="x => x.CourseName" Title="Course"/>
6259
<PropertyColumn Property="x => x.ExerciseName" Title="Exercise"/>
63-
<TemplateColumn Title="Repo URL">
60+
<TemplateColumn Title="Repo URL" Sortable="true" SortBy="dashboard => dashboard.GithubRepoUrl">
6461
<CellTemplate>
6562
<MudLink Href="@context.Item.GithubRepoUrl">
6663
@context.Item.GithubRepoUrl
6764
</MudLink>
6865
</CellTemplate>
6966
</TemplateColumn>
7067
<PropertyColumn Property="x => x.StudentNeptun" Title="Neptun"/>
71-
<TemplateColumn Title="PRs">
68+
<TemplateColumn T="Dashboard" Title="PRs" Class="pipa" Sortable="true" SortBy="@SortByPr">
7269
<CellTemplate>
7370
<MudTooltip Text="@PrTooltip(context.Item)">
7471
<MudLink Href="@JoinPullRequests(context.Item)">
@@ -78,30 +75,38 @@
7875
</CellTemplate>
7976
</TemplateColumn>
8077
@* <PropertyColumn Property="x => JoinCiWorkflows(x)" Title="Workflows"/> *@
81-
<TemplateColumn Title="Score">
78+
<TemplateColumn T="Dashboard" Title="Score" Class="pipa" Sortable="true" SortBy="@SortByScore">
8279
<CellTemplate>
8380
<MudTooltip Text="@ScoreTooltip(context.Item)">
8481
@JoinScore(context.Item)
8582
</MudTooltip>
8683
</CellTemplate>
8784
</TemplateColumn>
88-
<TemplateColumn Title="" T="Dashboard">
85+
<TemplateColumn Title="" T="Dashboard" Class="pipa" Sortable="true" SortBy="@SortByState">
8986
<CellTemplate>
9087
@if (MergedEntry(context.Item))
9188
{
92-
<MudIcon Icon="@Icons.Material.Filled.Verified" Color="Color.Success"/>
89+
<MudTooltip Text="Merged" Placement="Placement.Top">
90+
<MudIcon Icon="@Icons.Material.Filled.Verified" Color="Color.Success"/>
91+
</MudTooltip>
9392
}
9493
else if (CheckedEntry(context.Item))
9594
{
96-
<MudIcon Icon="@Icons.Material.Filled.Check" Color="Color.Success"/>
95+
<MudTooltip Text="Teacher Checked" Placement="Placement.Top">
96+
<MudIcon Icon="@Icons.Material.Filled.Check" Color="Color.Success"/>
97+
</MudTooltip>
9798
}
9899
else if (CiRunOnEntry(context.Item))
99100
{
100-
<MudIcon Icon="@Icons.Material.Filled.Warning" Color="Color.Warning"/>
101+
<MudTooltip Text="CI Flow ran" Placement="Placement.Top">
102+
<MudIcon Icon="@Icons.Material.Filled.Warning" Color="Color.Warning"/>
103+
</MudTooltip>
101104
}
102105
else
103106
{
104-
<MudIcon Icon="@Icons.Material.Filled.Warning" Color="Color.Error"/>
107+
<MudTooltip Text="CI did not ran" Placement="Placement.Top">
108+
<MudIcon Icon="@Icons.Material.Filled.Warning" Color="Color.Error"/>
109+
</MudTooltip>
105110
}
106111
</CellTemplate>
107112
</TemplateColumn>
@@ -125,7 +130,7 @@
125130

126131
private string PrTooltip(Dashboard data)
127132
{
128-
return data.PullRequests?.FirstOrDefault()?.OpeningDate.ToString() ?? "";
133+
return data.PullRequests?.FirstOrDefault()?.OpeningDate.ToLocalTime().ToString() ?? "";
129134
}
130135

131136
private string JoinScore(Dashboard data)
@@ -154,6 +159,37 @@
154159
return string.Join(", ", data?.PullRequests?.FirstOrDefault()?.Scores.Select(x => $"{x.ScoreType.Type}: {x.Value}") ?? []);
155160
}
156161

162+
private object SortByState(Dashboard d)
163+
{
164+
if (MergedEntry(d))
165+
{
166+
return 4;
167+
}
168+
else if (CheckedEntry(d))
169+
{
170+
return 3;
171+
}
172+
else if (CiRunOnEntry(d))
173+
{
174+
return 2;
175+
}
176+
else
177+
{
178+
return 1;
179+
}
180+
}
181+
182+
private object SortByScore(Dashboard d)
183+
{
184+
// The first element is the most important, than the second, and so on, sum the values, but before that, multiply the value with 10^x, where x is the position of the element in the list
185+
return d.PullRequests?.FirstOrDefault()?.Scores.Aggregate(0L, (currentSum, number) => (currentSum * 10) + number.Value) ?? 0;
186+
}
187+
188+
private object SortByPr(Dashboard d)
189+
{
190+
return d.PullRequests?.FirstOrDefault()?.Url ?? "";
191+
}
192+
157193
#endregion
158194

159195
//Van e assignolt teacher?
@@ -162,8 +198,8 @@
162198
private LoadingComponent loadingRef;
163199

164200
private SubjectResponse? _selectedSubject = null;
165-
private string? _selectedCourse = null;
166-
private string? _selectedExercise = null;
201+
private IEnumerable<string> _selectedCourse = new List<string>();
202+
private IEnumerable<string> _selectedExercise = new List<string>();
167203
private IEnumerable<string>? _courses = new List<string>();
168204
private IEnumerable<string>? _tasks = new List<string>();
169205
private ICollection<Dashboard> _dashboardData = new List<Dashboard>();
@@ -199,18 +235,13 @@
199235
_filteredData = _dashboardData.ToList();
200236
_courses = _dashboardData?.Select(x => x.CourseName).Distinct();
201237
_tasks = _dashboardData?.Select(x => x.ExerciseName).Distinct();
238+
_selectedCourse = _courses?.ToList();
239+
_selectedExercise = _tasks?.ToList();
202240
}
203241

204-
private void CourseChanged()
205-
{
206-
_filteredData = _dashboardData.Where(x => (_selectedCourse == null || x.CourseName == _selectedCourse) && (_selectedExercise == null || x.ExerciseName == _selectedExercise)).ToList();
207-
_courses = _dashboardData?.Select(x => x.CourseName).Distinct();
208-
_tasks = _dashboardData?.Select(x => x.ExerciseName).Distinct();
209-
}
210-
211-
private void ExerciseChanged()
242+
private void FilterChanged()
212243
{
213-
_filteredData = _dashboardData.Where(x => (_selectedCourse == null || x.CourseName == _selectedCourse) && (_selectedExercise == null || x.ExerciseName == _selectedExercise)).ToList();
244+
_filteredData = _dashboardData.Where(x => (_selectedCourse.Contains(x.CourseName)) && ( _selectedExercise.Contains(x.ExerciseName))).ToList();
214245
_courses = _dashboardData?.Select(x => x.CourseName).Distinct();
215246
_tasks = _dashboardData?.Select(x => x.ExerciseName).Distinct();
216247
}

grade-management-new/GradeManagement.Client/Program.cs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,10 @@ public static async Task Main(string[] args)
4949
builder.Services.AddTransient(sp =>
5050
new ExceptionMessageHandler(sp.GetRequiredService<CrudSnackbarService>()));
5151

52-
// Registering HttpClient that uses our custom handler
53-
builder.Services.AddHttpClient(SubjectApi,
54-
client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
55-
.AddHttpMessageHandler<ExceptionMessageHandler>()
56-
.AddHttpMessageHandler<AuthorizationMessageHandler>();
57-
58-
builder.Services.AddScoped<SubjectClient>(sp =>
59-
new SubjectClient(sp.GetRequiredService<IHttpClientFactory>().CreateClient(SubjectApi)));
60-
builder.Services.AddSingleton<SubjectService>(sp =>
61-
{
62-
var serviceProvider = sp.CreateScope().ServiceProvider;
63-
return new SubjectService(serviceProvider);
64-
});
52+
builder.Services.AddSingleton<SelectedSubjectService>();
53+
builder.Services.AddSingleton<CurrentUserService>();
6554

66-
builder.Services.AddTransient(sp => new SubjectHeaderHandler(sp.GetRequiredService<SubjectService>()));
55+
builder.Services.AddTransient(sp => new SubjectHeaderHandler(sp.GetRequiredService<SelectedSubjectService>()));
6756

6857
// Registering HttpClient that uses our custom handler
6958
builder.Services.AddHttpClient(ServerApi,
@@ -73,6 +62,9 @@ public static async Task Main(string[] args)
7362
.AddHttpMessageHandler<SubjectHeaderHandler>();
7463

7564

65+
builder.Services.AddScoped<SubjectClient>(sp =>
66+
new SubjectClient(sp.GetRequiredService<IHttpClientFactory>().CreateClient(ServerApi)));
67+
builder.Services.AddScoped<SubjectService>();
7668
builder.Services.AddScoped<CourseClient>(sp =>
7769
new CourseClient(sp.GetRequiredService<IHttpClientFactory>().CreateClient(ServerApi)));
7870
builder.Services.AddScoped<SemesterClient>(sp =>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using GradeManagement.Client.Network;
2+
3+
namespace GradeManagement.Client.Services;
4+
5+
public class CurrentUserService
6+
{
7+
public User? User { get; set; }
8+
}

0 commit comments

Comments
 (0)