From 0883d2332e33edeea3a94ebb3efe907749e30a5e Mon Sep 17 00:00:00 2001 From: jay-tux Date: Tue, 10 Jun 2025 16:41:02 +0200 Subject: [PATCH] Fix loading bug --- .../com/jaytux/grader/ui/Assignments.kt | 77 +++++++------------ .../com/jaytux/grader/viewmodel/DbState.kt | 21 +++-- 2 files changed, 41 insertions(+), 57 deletions(-) diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Assignments.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Assignments.kt index 8d06552..6740048 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Assignments.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Assignments.kt @@ -12,11 +12,9 @@ import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.layout import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.dp -import com.jaytux.grader.data.GroupAssignment import com.jaytux.grader.data.GroupAssignmentCriterion import com.jaytux.grader.data.SoloAssignmentCriterion import com.jaytux.grader.data.Student @@ -26,7 +24,6 @@ import com.jaytux.grader.viewmodel.SoloAssignmentState import com.mohamedrejeb.richeditor.model.rememberRichTextState import com.mohamedrejeb.richeditor.ui.material3.OutlinedRichTextEditor import kotlinx.datetime.LocalDateTime -import org.jetbrains.exposed.sql.transactions.inTopLevelTransaction @Composable fun GroupAssignmentView(state: GroupAssignmentState) { @@ -189,7 +186,7 @@ fun groupTaskWidget( @Composable fun groupFeedback(state: GroupAssignmentState, fdbk: GroupAssignmentState.LocalGFeedback) { val (group, feedback, individual) = fdbk - var idx by remember(fdbk) { mutableStateOf(0) } + var studentIdx by remember(fdbk) { mutableStateOf(0) } var critIdx by remember(fdbk) { mutableStateOf(0) } val criteria by state.criteria.entities val suggestions by state.autofill.entities @@ -199,8 +196,8 @@ fun groupFeedback(state: GroupAssignmentState, fdbk: GroupAssignmentState.LocalG LazyColumn(Modifier.fillMaxHeight().padding(10.dp)) { item { Surface( - Modifier.fillMaxWidth().clickable { idx = 0 }, - tonalElevation = if (idx == 0) 50.dp else 0.dp, + Modifier.fillMaxWidth().clickable { studentIdx = 0 }, + tonalElevation = if (studentIdx == 0) 50.dp else 0.dp, shape = MaterialTheme.shapes.medium ) { Text("Group feedback", Modifier.padding(5.dp), fontStyle = FontStyle.Italic) @@ -210,8 +207,8 @@ fun groupFeedback(state: GroupAssignmentState, fdbk: GroupAssignmentState.LocalG itemsIndexed(individual.toList()) { i, (student, details) -> val (role, _) = details Surface( - Modifier.fillMaxWidth().clickable { idx = i + 1 }, - tonalElevation = if (idx == i + 1) 50.dp else 0.dp, + Modifier.fillMaxWidth().clickable { studentIdx = i + 1 }, + tonalElevation = if (studentIdx == i + 1) 50.dp else 0.dp, shape = MaterialTheme.shapes.medium ) { Text("${student.name} (${role ?: "no role"})", Modifier.padding(5.dp)) @@ -220,45 +217,25 @@ fun groupFeedback(state: GroupAssignmentState, fdbk: GroupAssignmentState.LocalG } } - val updateGrade = { grade: String -> - if(idx == 0) { - state.upsertGroupFeedback(group, feedback.global?.feedback ?: "", grade) - } - else { - val ind = individual[idx - 1] - val glob = ind.second.second.global - state.upsertIndividualFeedback(ind.first, group, glob?.feedback ?: "", grade) - } - } - - val updateFeedback = { fdbk: String -> - if(idx == 0) { - if(critIdx == 0) { - state.upsertGroupFeedback(group, fdbk, feedback.global?.grade ?: "", null) - } - else { - val current = feedback.byCriterion[critIdx - 1] - state.upsertGroupFeedback(group, fdbk, current.entry?.grade ?: "", current.criterion) - } - } - else { - val ind = individual[idx - 1] - if(critIdx == 0) { - val entry = ind.second.second - state.upsertIndividualFeedback(ind.first, group, fdbk, entry.global?.grade ?: "", null) - } - else { - val entry = ind.second.second.byCriterion[critIdx - 1] - state.upsertIndividualFeedback(ind.first, group, fdbk, entry.entry?.grade ?: "", entry.criterion) - } + val onSave = { grade: String, fdbk: String -> + when { + studentIdx == 0 && critIdx == 0 -> state.upsertGroupFeedback(group, fdbk, grade) + studentIdx == 0 && critIdx != 0 -> state.upsertGroupFeedback(group, fdbk, grade, criteria[critIdx - 1]) + studentIdx != 0 && critIdx == 0 -> state.upsertIndividualFeedback(individual[studentIdx - 1].first, group, fdbk, grade) + else -> state.upsertIndividualFeedback(individual[studentIdx - 1].first, group, fdbk, grade, criteria[critIdx - 1]) } } groupFeedbackPane( - criteria, critIdx, { critIdx = it }, feedback.global, - if(critIdx == 0) feedback.global else feedback.byCriterion[critIdx - 1].entry, - suggestions, updateGrade, updateFeedback, Modifier.weight(0.75f).padding(10.dp), - key = idx to critIdx + criteria, critIdx, { critIdx = it }, + when { + studentIdx == 0 && critIdx == 0 -> feedback.global + studentIdx == 0 && critIdx != 0 -> feedback.byCriterion[critIdx - 1].entry + studentIdx != 0 && critIdx == 0 -> individual[studentIdx - 1].second.second.global + else -> individual[studentIdx - 1].second.second.byCriterion[critIdx - 1].entry + }, + suggestions, onSave, Modifier.weight(0.75f).padding(10.dp), + key = studentIdx to critIdx ) } } @@ -268,19 +245,17 @@ fun groupFeedbackPane( criteria: List, currentCriterion: Int, onSelectCriterion: (Int) -> Unit, - globFeedback: GroupAssignmentState.FeedbackEntry?, - criterionFeedback: GroupAssignmentState.FeedbackEntry?, + rawFeedback: GroupAssignmentState.FeedbackEntry?, autofill: List, - onSetGrade: (String) -> Unit, - onSetFeedback: (String) -> Unit, + onSave: (String, String) -> Unit, modifier: Modifier = Modifier, key: Any? = null ) { - var grade by remember(globFeedback, key) { mutableStateOf(globFeedback?.grade ?: "") } + var grade by remember(rawFeedback, key) { mutableStateOf(rawFeedback?.grade ?: "") } val feedback = rememberRichTextState() - LaunchedEffect(currentCriterion, criteria, criterionFeedback, key) { - feedback.setMarkdown(criterionFeedback?.feedback ?: "") + LaunchedEffect(currentCriterion, criteria, rawFeedback, key) { + feedback.setMarkdown(rawFeedback?.feedback ?: "") } Column(modifier) { @@ -289,7 +264,7 @@ fun groupFeedbackPane( OutlinedTextField(grade, { grade = it }, Modifier.weight(0.2f)) Spacer(Modifier.weight(0.6f)) Button( - { onSetGrade(grade); onSetFeedback(feedback.toMarkdown()) }, + { onSave(grade, feedback.toMarkdown()) }, Modifier.weight(0.2f).align(Alignment.CenterVertically) ) { Text("Save") diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/DbState.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/DbState.kt index 037a119..675e9a2 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/DbState.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/DbState.kt @@ -171,10 +171,14 @@ class EditionState(val edition: Edition) { fun newSoloAssignment(name: String) { transaction { - SoloAssignment.new { + val assign = SoloAssignment.new { this.name = name; this.edition = this@EditionState.edition; assignment = ""; deadline = now() this.number = nextIdx() } + val global = SoloAssignmentCriterion.new { + this.name = "_global"; this.description = "[Global] Meta-criterion for $name"; this.assignment = assign + } + assign.globalCriterion = global solo.refresh() } } @@ -186,10 +190,14 @@ class EditionState(val edition: Edition) { } fun newGroupAssignment(name: String) { transaction { - GroupAssignment.new { + val assign = GroupAssignment.new { this.name = name; this.edition = this@EditionState.edition; assignment = ""; deadline = now() this.number = nextIdx() } + val global = GroupAssignmentCriterion.new { + this.name = "_global"; this.description = "[Global] Meta-criterion for $name"; this.assignment = assign + } + assign.globalCriterion = global groupAs.refresh() } } @@ -494,7 +502,7 @@ class GroupAssignmentState(val assignment: GroupAssignment) { private fun Transaction.loadFeedback(): List> { val allCrit = GroupAssignmentCriterion.find { GroupAssignmentCriteria.assignmentId eq assignment.id - }.filter { it.id != assignment.globalCriterion.id } + }//.filter { it.id != assignment.globalCriterion.id } return Group.find { (Groups.editionId eq assignment.edition.id) @@ -525,11 +533,12 @@ class GroupAssignmentState(val assignment: GroupAssignment) { val student = it.student val role = it.role - val forSt = (IndividualFeedbacks innerJoin Groups innerJoin GroupStudents) + val forSt = (IndividualFeedbacks innerJoin Groups) .selectAll().where { (IndividualFeedbacks.assignmentId eq assignment.id) and - (GroupStudents.studentId eq student.id) and (Groups.id eq group.id) + (IndividualFeedbacks.studentId eq student.id) and (Groups.id eq group.id) }.map { row -> + val stdId = row[IndividualFeedbacks.studentId] val crit = GroupAssignmentCriterion[row[IndividualFeedbacks.criterionId]] val fdbk = row[IndividualFeedbacks.feedback] val grade = row[IndividualFeedbacks.grade] @@ -537,7 +546,7 @@ class GroupAssignmentState(val assignment: GroupAssignment) { crit to FeedbackEntry(fdbk, grade) } - val global = forSt.firstOrNull { it.first == assignment.globalCriterion.id }?.second + val global = forSt.firstOrNull { it.first.id == assignment.globalCriterion.id }?.second val byCrit_ = forSt .filter { it.first != assignment.globalCriterion.id } .map { LocalCriterionFeedback(it.first, it.second) }