diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/DSL.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/DSL.kt index c27d459..e595594 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/DSL.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/DSL.kt @@ -115,7 +115,7 @@ object StudentToGroupEvaluation : CompositeIdTable("stToGrEv") { val grade = varchar("grade", 32) val note = text("note") - override val primaryKey = PrimaryKey(peerEvaluationId) + override val primaryKey = PrimaryKey(peerEvaluationId, studentId) } object StudentToStudentEvaluation : CompositeIdTable("stToStEv") { 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 15b3c77..fdde435 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Assignments.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Assignments.kt @@ -255,11 +255,11 @@ fun PeerEvaluationView(state: PeerEvaluationState) { Column(Modifier.padding(10.dp)) { TabRow(idx) { contents.forEachIndexed { i, it -> - Tab(idx == i, { idx = i }) { Text(it.group.name) } + Tab(idx == i, { idx = i; editing = null }) { Text(it.group.name) } } } Spacer(Modifier.height(10.dp)) - + Row { val current = contents[idx] val horScroll = rememberLazyListState() @@ -316,7 +316,7 @@ fun PeerEvaluationView(state: PeerEvaluationState) { item { VLine() } } } - MeasuredLazyColumn { + MeasuredLazyColumn(key = idx) { measuredItem { HLine() } items(current.students) { (from, glob, map) -> Row(Modifier.height(cellSize)) { @@ -348,8 +348,9 @@ fun PeerEvaluationView(state: PeerEvaluationState) { editing?.let { Column(Modifier.weight(0.5f)) { val (from, to, data) = it - var sGrade by remember(idx) { mutableStateOf(data?.grade ?: "") } - var sMsg by remember(idx) { mutableStateOf(data?.feedback ?: "") } + + var sGrade by remember(editing) { mutableStateOf(data?.grade ?: "") } + var sMsg by remember(editing) { mutableStateOf(data?.feedback ?: "") } Box(Modifier.padding(5.dp)) { to?.let { s2 -> @@ -365,7 +366,7 @@ fun PeerEvaluationView(state: PeerEvaluationState) { OutlinedTextField(sGrade, { sGrade = it }, Modifier.weight(0.2f)) Spacer(Modifier.weight(0.6f)) Button( - { state.upsertIndividualFeedback(from, to, sMsg, sGrade) }, + { state.upsertIndividualFeedback(from, to, sGrade, sMsg); editing = null }, Modifier.weight(0.2f).align(Alignment.CenterVertically), enabled = sGrade.isNotBlank() || sMsg.isNotBlank() ) { @@ -386,7 +387,7 @@ fun PeerEvaluationView(state: PeerEvaluationState) { Row { Text("Group-level notes", Modifier.weight(1f).align(Alignment.CenterVertically), fontWeight = FontWeight.Bold) Button( - { state.upsertGroupFeedback(current.group, groupLevel) }, + { state.upsertGroupFeedback(current.group, groupLevel); editing = null }, enabled = groupLevel != contents[idx].content ) { Text("Update") } } diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/MeasuredLazyColumn.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/MeasuredLazyColumn.kt index d6699c1..5077861 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/MeasuredLazyColumn.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/MeasuredLazyColumn.kt @@ -24,8 +24,8 @@ interface MeasuredLazyItemScope : LazyItemScope { } @Composable -fun MeasuredLazyColumn(modifier: Modifier = Modifier, content: MeasuredLazyListScope.() -> Unit) { - val measuredWidth = remember { mutableStateOf(0.dp) } +fun MeasuredLazyColumn(modifier: Modifier = Modifier, key: Any? = null, content: MeasuredLazyListScope.() -> Unit) { + val measuredWidth = remember(key) { mutableStateOf(0.dp) } LazyColumn(modifier.onGloballyPositioned { measuredWidth.value = it.size.width.dp }) { diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Widgets.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Widgets.kt index 9ebe998..fe51e68 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Widgets.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Widgets.kt @@ -415,19 +415,22 @@ fun SelectEditDeleteRow( @Composable fun FromTo(size: Dp) { - Box(Modifier.width(size).height(size)) { + var w by remember { mutableStateOf(0) } + var h by remember { mutableStateOf(0) } + Box(Modifier.width(size).height(size).onGloballyPositioned { + w = it.size.width + h = it.size.height + }) { Box(Modifier.align(Alignment.BottomStart)) { Text("Evaluator", fontWeight = FontWeight.Bold) } - Box( - Modifier.align(Alignment.TopEnd) - ) { + Box { Text("Evaluated", Modifier.graphicsLayer { rotationZ = -90f + translationX = w - 15f + translationY = h - 15f transformOrigin = TransformOrigin(0f, 0.5f) - translationX = size.value / 2f - 15f - translationY = size.value - 15f }, fontWeight = FontWeight.Bold) } } @@ -442,7 +445,7 @@ fun PEGradeWidget( ) = Box(modifier.padding(2.dp)) { Selectable(isSelected, onSelect, onDeselect) { Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { - Text(grade?.let { if(it.grade.isNotBlank()) it.grade else if(it.feedback.isNotBlank()) "n/a" else null } ?: "none") + Text(grade?.let { if(it.grade.isNotBlank()) it.grade else if(it.feedback.isNotBlank()) "(other)" else null } ?: "none") } } } 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 aa0a258..5be3ffc 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/DbState.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/DbState.kt @@ -604,17 +604,17 @@ class PeerEvaluationState(val evaluation: PeerEvaluation) { val contents = RawDbState { loadContents() } private fun Transaction.loadContents(): List { - val found = PeerEvaluationContents.selectAll().where { - PeerEvaluationContents.peerEvaluationId eq evaluation.id + val found = (Groups leftJoin PeerEvaluationContents).selectAll().where { + Groups.editionId eq evaluation.edition.id }.associate { gc -> - val group = Group[gc[PeerEvaluationContents.groupId]] - val content = gc[PeerEvaluationContents.content] + val group = Group[gc[Groups.id]] + val content = gc[PeerEvaluationContents.content] ?: "" val students = group.students.map { student1 -> val others = group.students.map { student2 -> val eval = StudentToStudentEvaluation.selectAll().where { StudentToStudentEvaluation.peerEvaluationId eq evaluation.id and - (StudentToStudentEvaluation.studentIdTo eq student1.id) and - (StudentToStudentEvaluation.studentIdFrom eq student2.id) + (StudentToStudentEvaluation.studentIdFrom eq student1.id) and + (StudentToStudentEvaluation.studentIdTo eq student2.id) }.firstOrNull() student2 to eval?.let { Student2StudentEntry(