|
1 | 1 | @page "/" |
2 | 2 | @using GradeManagement.Client.Components.NewDialogs |
| 3 | +@using MudExtensions |
3 | 4 | @layout AuthenticatedLayout |
4 | 5 |
|
5 | 6 | @inject SubjectService SubjectService |
|
14 | 15 |
|
15 | 16 | <style> |
16 | 17 | .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' |
18 | 19 | } |
19 | 20 |
|
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'; |
22 | 23 | } |
23 | 24 |
|
24 | | - .sort-direction-icon.mud-direction-desc { |
| 25 | + .sort-direction-icon.mud-direction-asc { |
25 | 26 | --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' |
26 | 27 | } |
27 | 28 |
|
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 { |
29 | 30 | d: path(var(--path-svg)) |
30 | 31 | } |
31 | 32 | </style> |
|
35 | 36 | <MudDivider Class="mb-4"/> |
36 | 37 |
|
37 | 38 | <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) |
42 | 41 | { |
43 | | - <MudSelectItem Value="@course">@course</MudSelectItem> |
| 42 | + <MudSelectItemExtended T="string" Value="@course" Text="@course"/> |
44 | 43 | } |
45 | | - </MudSelect> |
| 44 | + </MudSelectExtended> |
46 | 45 | <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) |
51 | 48 | { |
52 | | - <MudSelectItem Value="@task">@task</MudSelectItem> |
| 49 | + <MudSelectItemExtended T="string" Value="@task" Text="@task"/> |
53 | 50 | } |
54 | | - </MudSelect> |
| 51 | + </MudSelectExtended> |
55 | 52 | <MudSpacer/> |
56 | 53 |
|
57 | 54 | <MudIconButton Icon="@Icons.Material.Filled.Download" Color="Color.Inherit" Edge="Edge.End" Size="Size.Large"/> |
|
60 | 57 | <Columns> |
61 | 58 | <PropertyColumn Property="x => x.CourseName" Title="Course"/> |
62 | 59 | <PropertyColumn Property="x => x.ExerciseName" Title="Exercise"/> |
63 | | - <TemplateColumn Title="Repo URL"> |
| 60 | + <TemplateColumn Title="Repo URL" Sortable="true" SortBy="dashboard => dashboard.GithubRepoUrl"> |
64 | 61 | <CellTemplate> |
65 | 62 | <MudLink Href="@context.Item.GithubRepoUrl"> |
66 | 63 | @context.Item.GithubRepoUrl |
67 | 64 | </MudLink> |
68 | 65 | </CellTemplate> |
69 | 66 | </TemplateColumn> |
70 | 67 | <PropertyColumn Property="x => x.StudentNeptun" Title="Neptun"/> |
71 | | - <TemplateColumn Title="PRs"> |
| 68 | + <TemplateColumn T="Dashboard" Title="PRs" Class="pipa" Sortable="true" SortBy="@SortByPr"> |
72 | 69 | <CellTemplate> |
73 | 70 | <MudTooltip Text="@PrTooltip(context.Item)"> |
74 | 71 | <MudLink Href="@JoinPullRequests(context.Item)"> |
|
78 | 75 | </CellTemplate> |
79 | 76 | </TemplateColumn> |
80 | 77 | @* <PropertyColumn Property="x => JoinCiWorkflows(x)" Title="Workflows"/> *@ |
81 | | - <TemplateColumn Title="Score"> |
| 78 | + <TemplateColumn T="Dashboard" Title="Score" Class="pipa" Sortable="true" SortBy="@SortByScore"> |
82 | 79 | <CellTemplate> |
83 | 80 | <MudTooltip Text="@ScoreTooltip(context.Item)"> |
84 | 81 | @JoinScore(context.Item) |
85 | 82 | </MudTooltip> |
86 | 83 | </CellTemplate> |
87 | 84 | </TemplateColumn> |
88 | | - <TemplateColumn Title="" T="Dashboard"> |
| 85 | + <TemplateColumn Title="" T="Dashboard" Class="pipa" Sortable="true" SortBy="@SortByState"> |
89 | 86 | <CellTemplate> |
90 | 87 | @if (MergedEntry(context.Item)) |
91 | 88 | { |
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> |
93 | 92 | } |
94 | 93 | else if (CheckedEntry(context.Item)) |
95 | 94 | { |
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> |
97 | 98 | } |
98 | 99 | else if (CiRunOnEntry(context.Item)) |
99 | 100 | { |
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> |
101 | 104 | } |
102 | 105 | else |
103 | 106 | { |
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> |
105 | 110 | } |
106 | 111 | </CellTemplate> |
107 | 112 | </TemplateColumn> |
|
125 | 130 |
|
126 | 131 | private string PrTooltip(Dashboard data) |
127 | 132 | { |
128 | | - return data.PullRequests?.FirstOrDefault()?.OpeningDate.ToString() ?? ""; |
| 133 | + return data.PullRequests?.FirstOrDefault()?.OpeningDate.ToLocalTime().ToString() ?? ""; |
129 | 134 | } |
130 | 135 |
|
131 | 136 | private string JoinScore(Dashboard data) |
|
154 | 159 | return string.Join(", ", data?.PullRequests?.FirstOrDefault()?.Scores.Select(x => $"{x.ScoreType.Type}: {x.Value}") ?? []); |
155 | 160 | } |
156 | 161 |
|
| 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 | + |
157 | 193 | #endregion |
158 | 194 |
|
159 | 195 | //Van e assignolt teacher? |
|
162 | 198 | private LoadingComponent loadingRef; |
163 | 199 |
|
164 | 200 | 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>(); |
167 | 203 | private IEnumerable<string>? _courses = new List<string>(); |
168 | 204 | private IEnumerable<string>? _tasks = new List<string>(); |
169 | 205 | private ICollection<Dashboard> _dashboardData = new List<Dashboard>(); |
|
199 | 235 | _filteredData = _dashboardData.ToList(); |
200 | 236 | _courses = _dashboardData?.Select(x => x.CourseName).Distinct(); |
201 | 237 | _tasks = _dashboardData?.Select(x => x.ExerciseName).Distinct(); |
| 238 | + _selectedCourse = _courses?.ToList(); |
| 239 | + _selectedExercise = _tasks?.ToList(); |
202 | 240 | } |
203 | 241 |
|
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() |
212 | 243 | { |
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(); |
214 | 245 | _courses = _dashboardData?.Select(x => x.CourseName).Distinct(); |
215 | 246 | _tasks = _dashboardData?.Select(x => x.ExerciseName).Distinct(); |
216 | 247 | } |
|
0 commit comments