UI changes: can go back in edition view
This commit is contained in:
parent
b69b46afee
commit
63c4197cfc
|
@ -20,8 +20,6 @@ import com.mohamedrejeb.richeditor.ui.material3.OutlinedRichTextEditor
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun GroupAssignmentView(state: GroupAssignmentState) {
|
fun GroupAssignmentView(state: GroupAssignmentState) {
|
||||||
val (course, edition) = state.editionCourse
|
|
||||||
val name by state.name
|
|
||||||
val task by state.task
|
val task by state.task
|
||||||
val deadline by state.deadline
|
val deadline by state.deadline
|
||||||
val allFeedback by state.feedback.entities
|
val allFeedback by state.feedback.entities
|
||||||
|
@ -29,7 +27,6 @@ fun GroupAssignmentView(state: GroupAssignmentState) {
|
||||||
var idx by remember(state) { mutableStateOf(0) }
|
var idx by remember(state) { mutableStateOf(0) }
|
||||||
|
|
||||||
Column(Modifier.padding(10.dp)) {
|
Column(Modifier.padding(10.dp)) {
|
||||||
PaneHeader(name, "group assignment", course, edition)
|
|
||||||
if(allFeedback.any { it.second.feedback == null }) {
|
if(allFeedback.any { it.second.feedback == null }) {
|
||||||
Text("Groups in bold have no feedback yet.", fontStyle = FontStyle.Italic)
|
Text("Groups in bold have no feedback yet.", fontStyle = FontStyle.Italic)
|
||||||
}
|
}
|
||||||
|
@ -150,8 +147,6 @@ fun groupFeedback(state: GroupAssignmentState, fdbk: GroupAssignmentState.LocalG
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun SoloAssignmentView(state: SoloAssignmentState) {
|
fun SoloAssignmentView(state: SoloAssignmentState) {
|
||||||
val name by state.name
|
|
||||||
val (course, edition) = state.editionCourse
|
|
||||||
val task by state.task
|
val task by state.task
|
||||||
val deadline by state.deadline
|
val deadline by state.deadline
|
||||||
val suggestions by state.autofill.entities
|
val suggestions by state.autofill.entities
|
||||||
|
@ -160,7 +155,6 @@ fun SoloAssignmentView(state: SoloAssignmentState) {
|
||||||
var idx by remember(state) { mutableStateOf(0) }
|
var idx by remember(state) { mutableStateOf(0) }
|
||||||
|
|
||||||
Column(Modifier.padding(10.dp)) {
|
Column(Modifier.padding(10.dp)) {
|
||||||
PaneHeader(name, "individual assignment", course, edition)
|
|
||||||
Row {
|
Row {
|
||||||
Surface(Modifier.weight(0.25f), tonalElevation = 10.dp) {
|
Surface(Modifier.weight(0.25f), tonalElevation = 10.dp) {
|
||||||
LazyColumn(Modifier.fillMaxHeight().padding(10.dp)) {
|
LazyColumn(Modifier.fillMaxHeight().padding(10.dp)) {
|
||||||
|
|
|
@ -15,10 +15,6 @@ import androidx.compose.ui.window.*
|
||||||
import com.jaytux.grader.data.*
|
import com.jaytux.grader.data.*
|
||||||
import com.jaytux.grader.viewmodel.*
|
import com.jaytux.grader.viewmodel.*
|
||||||
|
|
||||||
enum class OpenPanel(val tabName: String) {
|
|
||||||
Student("Students"), Group("Groups"), Assignment("Assignments")
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Navigators(
|
data class Navigators(
|
||||||
val student: (Student) -> Unit,
|
val student: (Student) -> Unit,
|
||||||
val group: (Group) -> Unit,
|
val group: (Group) -> Unit,
|
||||||
|
@ -36,41 +32,41 @@ fun EditionView(state: EditionState) = Row(Modifier.padding(0.dp)) {
|
||||||
val mergedAssignments by remember(solo, groupAs) {
|
val mergedAssignments by remember(solo, groupAs) {
|
||||||
mutableStateOf(Assignment.merge(groupAs, solo))
|
mutableStateOf(Assignment.merge(groupAs, solo))
|
||||||
}
|
}
|
||||||
var selected by remember { mutableStateOf(-1) }
|
val hist by state.history
|
||||||
var tab by remember { mutableStateOf(OpenPanel.Assignment) }
|
|
||||||
|
|
||||||
val navs = Navigators(
|
val navs = Navigators(
|
||||||
student = { tab = OpenPanel.Student; selected = students.indexOfFirst { s -> s.id == it.id } },
|
student = { state.navTo(OpenPanel.Student, students.indexOfFirst{ s -> s.id == it.id }) },
|
||||||
group = { tab = OpenPanel.Group; selected = groups.indexOfFirst { g -> g.id == it.id } },
|
group = { state.navTo(OpenPanel.Group, groups.indexOfFirst { g -> g.id == it.id }) },
|
||||||
assignment = { tab = OpenPanel.Assignment; selected = mergedAssignments.indexOfFirst { a -> a.id() == it.id() } }
|
assignment = { state.navTo(OpenPanel.Assignment, mergedAssignments.indexOfFirst { a -> a.id() == it.id() }) }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val (id, tab) = hist.last()
|
||||||
Surface(Modifier.weight(0.25f), tonalElevation = 5.dp) {
|
Surface(Modifier.weight(0.25f), tonalElevation = 5.dp) {
|
||||||
TabLayout(
|
TabLayout(
|
||||||
OpenPanel.entries,
|
OpenPanel.entries,
|
||||||
tab.ordinal,
|
tab.ordinal,
|
||||||
{ tab = OpenPanel.entries[it]; selected = -1 },
|
{ state.navTo(OpenPanel.entries[it]) },
|
||||||
{ Text(it.tabName) }
|
{ Text(it.tabName) }
|
||||||
) {
|
) {
|
||||||
when(tab) {
|
when(tab) {
|
||||||
OpenPanel.Student -> StudentPanel(
|
OpenPanel.Student -> StudentPanel(
|
||||||
course, edition, students, availableStudents, selected,
|
course, edition, students, availableStudents, id,
|
||||||
{ selected = it },
|
{ state.navTo(it) },
|
||||||
{ name, note, contact, add -> state.newStudent(name, contact, note, add) },
|
{ name, note, contact, add -> state.newStudent(name, contact, note, add) },
|
||||||
{ students -> state.addToCourse(students) },
|
{ students -> state.addToCourse(students) },
|
||||||
{ s, name -> state.setStudentName(s, name) }
|
{ s, name -> state.setStudentName(s, name) }
|
||||||
) { s -> state.delete(s) }
|
) { s -> state.delete(s) }
|
||||||
|
|
||||||
OpenPanel.Group -> GroupPanel(
|
OpenPanel.Group -> GroupPanel(
|
||||||
course, edition, groups, selected,
|
course, edition, groups, id,
|
||||||
{ selected = it },
|
{ state.navTo(it) },
|
||||||
{ name -> state.newGroup(name) },
|
{ name -> state.newGroup(name) },
|
||||||
{ g, name -> state.setGroupName(g, name) }
|
{ g, name -> state.setGroupName(g, name) }
|
||||||
) { g -> state.delete(g) }
|
) { g -> state.delete(g) }
|
||||||
|
|
||||||
OpenPanel.Assignment -> AssignmentPanel(
|
OpenPanel.Assignment -> AssignmentPanel(
|
||||||
course, edition, mergedAssignments, selected,
|
course, edition, mergedAssignments, id,
|
||||||
{ selected = it },
|
{ state.navTo(it) },
|
||||||
{ type, name -> state.newAssignment(type, name) },
|
{ type, name -> state.newAssignment(type, name) },
|
||||||
{ a, name -> state.setAssignmentTitle(a, name) }
|
{ a, name -> state.setAssignmentTitle(a, name) }
|
||||||
) { a -> state.delete(a) }
|
) { a -> state.delete(a) }
|
||||||
|
@ -78,15 +74,36 @@ fun EditionView(state: EditionState) = Row(Modifier.padding(0.dp)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(Modifier.weight(0.75f)) {
|
Column(Modifier.weight(0.75f)) {
|
||||||
if(selected != -1) {
|
Row {
|
||||||
|
IconButton({ state.back() }, enabled = hist.size >= 2) {
|
||||||
|
Icon(ChevronLeft, "Back", Modifier.size(MaterialTheme.typography.headlineMedium.fontSize.toDp()).align(Alignment.CenterVertically))
|
||||||
|
}
|
||||||
when(tab) {
|
when(tab) {
|
||||||
OpenPanel.Student -> StudentView(StudentState(students[selected], edition), navs)
|
OpenPanel.Student -> {
|
||||||
OpenPanel.Group -> GroupView(GroupState(groups[selected]), navs)
|
if(id == -1) PaneHeader("Nothing selected", "students", course, edition)
|
||||||
|
else PaneHeader(students[id].name, "student", course, edition)
|
||||||
|
}
|
||||||
|
OpenPanel.Group -> {
|
||||||
|
if(id == -1) PaneHeader("Nothing selected", "groups", course, edition)
|
||||||
|
else PaneHeader(groups[id].name, "group", course, edition)
|
||||||
|
}
|
||||||
OpenPanel.Assignment -> {
|
OpenPanel.Assignment -> {
|
||||||
when(val a = mergedAssignments[selected]) {
|
if(id == -1) PaneHeader("Nothing selected", "assignments", course, edition)
|
||||||
is Assignment.SAssignment -> SoloAssignmentView(SoloAssignmentState(a.assignment))
|
else PaneHeader(mergedAssignments[id].name(), "assignment", course, edition)
|
||||||
is Assignment.GAssignment -> GroupAssignmentView(GroupAssignmentState(a.assignment))
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Box(Modifier.weight(1f)) {
|
||||||
|
if (id != -1) {
|
||||||
|
when (tab) {
|
||||||
|
OpenPanel.Student -> StudentView(StudentState(students[id], edition), navs)
|
||||||
|
OpenPanel.Group -> GroupView(GroupState(groups[id]), navs)
|
||||||
|
OpenPanel.Assignment -> {
|
||||||
|
when (val a = mergedAssignments[id]) {
|
||||||
|
is Assignment.SAssignment -> SoloAssignmentView(SoloAssignmentState(a.assignment))
|
||||||
|
is Assignment.GAssignment -> GroupAssignmentView(GroupAssignmentState(a.assignment))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.DialogWindow
|
import androidx.compose.ui.window.DialogWindow
|
||||||
import androidx.compose.ui.window.WindowPosition
|
import androidx.compose.ui.window.WindowPosition
|
||||||
import androidx.compose.ui.window.rememberDialogState
|
import androidx.compose.ui.window.rememberDialogState
|
||||||
import com.jaytux.grader.data.Group
|
|
||||||
import com.jaytux.grader.data.Student
|
|
||||||
import com.jaytux.grader.maxN
|
import com.jaytux.grader.maxN
|
||||||
import com.jaytux.grader.viewmodel.GroupState
|
import com.jaytux.grader.viewmodel.GroupState
|
||||||
import com.jaytux.grader.viewmodel.StudentState
|
import com.jaytux.grader.viewmodel.StudentState
|
||||||
|
@ -31,7 +29,6 @@ fun StudentView(state: StudentState, nav: Navigators) {
|
||||||
val soloGrades by state.soloGrades.entities
|
val soloGrades by state.soloGrades.entities
|
||||||
|
|
||||||
Column(Modifier.padding(10.dp)) {
|
Column(Modifier.padding(10.dp)) {
|
||||||
PaneHeader(state.student.name, "student", state.editionCourse)
|
|
||||||
Row {
|
Row {
|
||||||
Column(Modifier.weight(0.45f)) {
|
Column(Modifier.weight(0.45f)) {
|
||||||
Column(Modifier.padding(10.dp).weight(0.35f)) {
|
Column(Modifier.padding(10.dp).weight(0.35f)) {
|
||||||
|
@ -150,12 +147,10 @@ fun GroupView(state: GroupState, nav: Navigators) {
|
||||||
val members by state.members.entities
|
val members by state.members.entities
|
||||||
val available by state.availableStudents.entities
|
val available by state.availableStudents.entities
|
||||||
val allRoles by state.roles.entities
|
val allRoles by state.roles.entities
|
||||||
val (course, edition) = state.course
|
|
||||||
|
|
||||||
var pickRole: Pair<String?, (String?) -> Unit>? by remember { mutableStateOf(null) }
|
var pickRole: Pair<String?, (String?) -> Unit>? by remember { mutableStateOf(null) }
|
||||||
|
|
||||||
Column(Modifier.padding(10.dp)) {
|
Column(Modifier.padding(10.dp)) {
|
||||||
PaneHeader(state.group.name, "group", course, edition)
|
|
||||||
Row {
|
Row {
|
||||||
Column(Modifier.weight(0.5f)) {
|
Column(Modifier.weight(0.5f)) {
|
||||||
Text("Students", style = MaterialTheme.typography.headlineSmall)
|
Text("Students", style = MaterialTheme.typography.headlineSmall)
|
||||||
|
|
|
@ -87,12 +87,18 @@ class EditionListState(val course: Course) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class OpenPanel(val tabName: String) {
|
||||||
|
Student("Students"), Group("Groups"), Assignment("Assignments")
|
||||||
|
}
|
||||||
|
|
||||||
class EditionState(val edition: Edition) {
|
class EditionState(val edition: Edition) {
|
||||||
val course = transaction { edition.course }
|
val course = transaction { edition.course }
|
||||||
val students = RawDbState { edition.soloStudents.sortAsc(Students.name).toList() }
|
val students = RawDbState { edition.soloStudents.sortAsc(Students.name).toList() }
|
||||||
val groups = RawDbState { edition.groups.sortAsc(Groups.name).toList() }
|
val groups = RawDbState { edition.groups.sortAsc(Groups.name).toList() }
|
||||||
val solo = RawDbState { edition.soloAssignments.sortAsc(SoloAssignments.name).toList() }
|
val solo = RawDbState { edition.soloAssignments.sortAsc(SoloAssignments.name).toList() }
|
||||||
val groupAs = RawDbState { edition.groupAssignments.sortAsc(GroupAssignments.name).toList() }
|
val groupAs = RawDbState { edition.groupAssignments.sortAsc(GroupAssignments.name).toList() }
|
||||||
|
private val _history = mutableStateOf(listOf(-1 to OpenPanel.Assignment))
|
||||||
|
val history = _history.immutable()
|
||||||
|
|
||||||
val availableStudents = RawDbState {
|
val availableStudents = RawDbState {
|
||||||
Student.find {
|
Student.find {
|
||||||
|
@ -217,6 +223,16 @@ class EditionState(val edition: Edition) {
|
||||||
is Assignment.GAssignment -> delete(assignment.assignment)
|
is Assignment.GAssignment -> delete(assignment.assignment)
|
||||||
is Assignment.SAssignment -> delete(assignment.assignment)
|
is Assignment.SAssignment -> delete(assignment.assignment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun navTo(panel: OpenPanel, id: Int = -1) {
|
||||||
|
_history.value += (id to panel)
|
||||||
|
}
|
||||||
|
fun navTo(id: Int) = navTo(_history.value.last().second, id)
|
||||||
|
fun back() {
|
||||||
|
var temp = _history.value.dropLast(1)
|
||||||
|
while(temp.last().first == -1 && temp.size >= 2) temp = temp.dropLast(1)
|
||||||
|
_history.value = temp
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StudentState(val student: Student, edition: Edition) {
|
class StudentState(val student: Student, edition: Edition) {
|
||||||
|
|
Loading…
Reference in New Issue