[UI/Grades] Allow filtering by semester for university grades

This commit is contained in:
Kuba Szczodrzyński 2025-02-01 21:40:46 +01:00
parent 30a77f1a99
commit 88cd18b8c6
No known key found for this signature in database
GPG Key ID: 43037AC62A600562
3 changed files with 73 additions and 9 deletions

View File

@ -137,9 +137,9 @@ class UsosApiExamReports(
value = value,
weight = if (countsIntoAverage == "T") gradeCategory?.weight ?: 0.0f else 0.0f,
color = (if (passes == true) 0xFF465FB3 else 0xFFB71C1C).toInt(),
category = "$termId$$typeDescription",
description = listOfNotNull(classType, sessionDescription).join(" - "),
comment = comment,
category = typeDescription,
description = listOfNotNull(classType, sessionDescription, comment).join(" - "),
comment = termId,
semester = 1,
teacherId = modificationAuthorId,
subjectId = data.getSubject(

View File

@ -28,6 +28,7 @@ import pl.szczodrzynski.edziennik.ui.grades.models.GradesAverages
import pl.szczodrzynski.edziennik.ui.grades.models.GradesSemester
import pl.szczodrzynski.edziennik.ui.grades.models.GradesStats
import pl.szczodrzynski.edziennik.ui.grades.models.GradesSubject
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
import pl.szczodrzynski.edziennik.utils.managers.GradesManager
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
@ -85,6 +86,35 @@ class GradesListFragment : Fragment(), CoroutineScope {
else -> grades
}
if (manager.isUniversity) {
val termIds = grades.map { it.comment }.toSet().toMutableList()
val termNames: MutableMap<String, String> = mutableMapOf()
// deserialize to a map of termId to (orderKey, termName)
val terms = app.profile.getStudentData("termNames", null)
?.let { app.gson.fromJson(it, termNames::class.java) }
?.mapValues { (_, value) -> value.split('$', limit = 2) }
?.mapValues { (_, value) -> Pair(value[0].toIntOrNull() ?: 0, value[1]) }
?: mapOf()
// sort by order key
termIds.sortByDescending { termId -> terms[termId]?.first ?: 0 }
// populate the dropdown
b.semesterLayout.isVisible = true
b.semesterDropdown.items = termIds.mapIndexed { id, termId ->
TextInputDropDown.Item(
id.toLong(),
terms[termId]?.second ?: termId ?: "-",
tag = termId,
)
}.toMutableList()
b.semesterDropdown.select(index = 0)
b.semesterDropdown.setOnChangeListener { item ->
b.semesterDropdown.select(item)
adapter.items = processGrades(items)
adapter.notifyDataSetChanged()
return@setOnChangeListener true
}
}
// load & configure the adapter
adapter.items = withContext(Dispatchers.Default) { processGrades(items) }
if (items.isNotNullNorEmpty() && b.list.adapter == null) {
@ -188,6 +218,8 @@ class GradesListFragment : Fragment(), CoroutineScope {
var semesterNumber = 0
var subject = GradesSubject(subjectId, "")
var semester = GradesSemester(0, 1)
val isUniversity = manager.isUniversity
val filterTermId = b.semesterDropdown.selected?.tag
val hideImproved = manager.hideImproved
@ -195,6 +227,9 @@ class GradesListFragment : Fragment(), CoroutineScope {
// by the subject ID, so it's easier and probably
// a bit faster to build all the models
for (grade in grades) {
if (isUniversity && filterTermId != null && grade.comment != filterTermId)
continue
/*if (grade.parentId != null && grade.parentId != -1L)
continue // the grade is hidden as a new, improved one is available*/
if (grade.subjectId != subjectId) {
@ -265,7 +300,7 @@ class GradesListFragment : Fragment(), CoroutineScope {
val stats = GradesStats()
if (manager.isUniversity) {
if (isUniversity) {
val semesterSum = mutableListOf<Float>()
val semesterCount = mutableListOf<Float>()
val totalSum = mutableListOf<Float>()
@ -283,6 +318,9 @@ class GradesListFragment : Fragment(), CoroutineScope {
// no points for this subject, simply assign
ectsPoints[grade.subjectId] = grade.weight
if (filterTermId != null && grade.comment != filterTermId)
continue
semesterSum.add(grade.value * grade.weight)
semesterCount.add(grade.weight)
}

View File

@ -37,13 +37,39 @@
app:drawableTopCompat="@drawable/ic_no_grades"
tools:visibility="visible" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
tools:listitem="@layout/grades_item_subject"
tools:visibility="visible" />
android:orientation="vertical">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/semesterLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:hint="@string/title_semester"
android:visibility="gone"
tools:visibility="visible">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/semesterDropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
tools:text="Semestr zimowy 2024/2025" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
tools:listitem="@layout/grades_item_subject"
tools:visibility="visible" />
</LinearLayout>
</FrameLayout>
</pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator>
</layout>