cards #8

Merged
faraphel merged 12 commits from cards into main 2024-06-13 15:12:13 +02:00
9 changed files with 208 additions and 76 deletions
Showing only changes of commit be801d5b31 - Show all commits

View file

@ -61,7 +61,7 @@ class TaskDatabaseApi(private val database: TaskDatabase) {
// TODO(Faraphel): should only be allowed to read data concerning the current class session // TODO(Faraphel): should only be allowed to read data concerning the current class session
NanoHTTPD.Method.HEAD -> { NanoHTTPD.Method.HEAD -> {
// check the permission of the session // check the permission of the session
if (taskSession.person.role.permissions.contains(TaskPermission.READ)) if (!taskSession.person.role.permissions.contains(TaskPermission.READ))
return NanoHTTPD.newFixedLengthResponse( return NanoHTTPD.newFixedLengthResponse(
NanoHTTPD.Response.Status.FORBIDDEN, NanoHTTPD.Response.Status.FORBIDDEN,
"text/plain", "text/plain",
@ -73,7 +73,7 @@ class TaskDatabaseApi(private val database: TaskDatabase) {
// get the data from the database // get the data from the database
NanoHTTPD.Method.GET -> { NanoHTTPD.Method.GET -> {
// check the permission of the session // check the permission of the session
if (taskSession.person.role.permissions.contains(TaskPermission.READ)) if (!taskSession.person.role.permissions.contains(TaskPermission.READ))
return NanoHTTPD.newFixedLengthResponse( return NanoHTTPD.newFixedLengthResponse(
NanoHTTPD.Response.Status.FORBIDDEN, NanoHTTPD.Response.Status.FORBIDDEN,
"text/plain", "text/plain",
@ -85,7 +85,7 @@ class TaskDatabaseApi(private val database: TaskDatabase) {
// insert the data into the database // insert the data into the database
NanoHTTPD.Method.POST -> { NanoHTTPD.Method.POST -> {
// check the permission of the session // check the permission of the session
if (taskSession.person.role.permissions.contains(TaskPermission.WRITE)) if (!taskSession.person.role.permissions.contains(TaskPermission.WRITE))
return NanoHTTPD.newFixedLengthResponse( return NanoHTTPD.newFixedLengthResponse(
NanoHTTPD.Response.Status.FORBIDDEN, NanoHTTPD.Response.Status.FORBIDDEN,
"text/plain", "text/plain",
@ -97,7 +97,7 @@ class TaskDatabaseApi(private val database: TaskDatabase) {
// delete the data from the database // delete the data from the database
NanoHTTPD.Method.DELETE -> { NanoHTTPD.Method.DELETE -> {
// check the permission of the session // check the permission of the session
if (taskSession.person.role.permissions.contains(TaskPermission.WRITE)) if (!taskSession.person.role.permissions.contains(TaskPermission.WRITE))
return NanoHTTPD.newFixedLengthResponse( return NanoHTTPD.newFixedLengthResponse(
NanoHTTPD.Response.Status.FORBIDDEN, NanoHTTPD.Response.Status.FORBIDDEN,
"text/plain", "text/plain",

View file

@ -21,6 +21,7 @@ data class TaskEntity (
@ColumnInfo("id") @PrimaryKey(autoGenerate = true) val id: Long = 0, @ColumnInfo("id") @PrimaryKey(autoGenerate = true) val id: Long = 0,
@ColumnInfo("title") val title: String, @ColumnInfo("title") val title: String,
@ColumnInfo("description") val description: String? = null, @ColumnInfo("description") val description: String? = null,
@ColumnInfo("order") val order: Int, ///< the order of the task in the list of the subject
@ColumnInfo("subject_id", index = true) val subjectId: Long, @ColumnInfo("subject_id", index = true) val subjectId: Long,
) : BaseEntity() { ) : BaseEntity() {

View file

@ -0,0 +1,117 @@
package com.faraphel.tasks_valider.database
import com.faraphel.tasks_valider.connectivity.task.session.TaskRole
import com.faraphel.tasks_valider.database.entities.*
fun populateTaskDatabaseTest(database: TaskDatabase) {
// classes
val (
classMiageId,
classIsriId,
) = database.classDao().insert(
ClassEntity(name="MIAGE"),
ClassEntity(name="ISRI")
)
val classMiage = database.classDao().getById(classMiageId)!!
val classIrsi = database.classDao().getById(classIsriId)!!
// persons
val (
personBillyId,
personBobbyId,
personBettyId,
) = database.personDao().insert(
PersonEntity(
"Billy", "Bob",
null,
"1234",
TaskRole.STUDENT
),
PersonEntity(
"Bobby", "Bob",
null,
"1234",
TaskRole.STUDENT
),
PersonEntity(
"Betty", "Bob",
null,
"1234",
TaskRole.STUDENT
)
)
val personBilly = database.personDao().getById(personBillyId)!!
val personBobby = database.personDao().getById(personBobbyId)!!
val personBetty = database.personDao().getById(personBettyId)!!
// relations class <=> persons
database.relationClassPersonDao().insert(
RelationClassPersonEntity(personBobby.id, classMiage.id),
RelationClassPersonEntity(personBilly.id, classMiage.id),
RelationClassPersonEntity(personBetty.id, classIrsi.id),
)
// subjects
val (
subjectAId,
subjectBId
) = database.subjectDao().insert(
SubjectEntity(
name="Type A"
),
SubjectEntity(
name="Type B"
)
)
val subjectA = database.subjectDao().getById(subjectAId)!!
val subjectB = database.subjectDao().getById(subjectBId)!!
// tasks
val (
taskA1Id,
taskA2Id,
taskA3Id,
taskB1Id,
taskB2Id,
) = database.taskDao().insert(
TaskEntity(
title = "Commencer A",
description = "Description 1",
order = 1,
subjectId = subjectA.id,
),
TaskEntity(
title = "Continuer A",
description = "Description 2",
order = 2,
subjectId = subjectA.id
),
TaskEntity(
title = "Finir A",
description = "Description 3",
order = 3,
subjectId = subjectA.id
),
TaskEntity(
title = "Commencer B",
description = "Description 1",
order = 1,
subjectId = subjectB.id,
),
TaskEntity(
title = "Finir B",
description = "Description 2",
order = 2,
subjectId = subjectB.id,
)
)
val taskA1 = database.taskDao().getById(taskA1Id)!!
val taskA2 = database.taskDao().getById(taskA2Id)!!
val taskA3 = database.taskDao().getById(taskA3Id)!!
val taskB1 = database.taskDao().getById(taskB1Id)!!
val taskB2 = database.taskDao().getById(taskB2Id)!!
}

View file

@ -1,4 +1,4 @@
package com.faraphel.tasks_valider.ui.screen.communication.internet.client package com.faraphel.tasks_valider.ui.screen.communication.internet
import android.app.Activity import android.app.Activity
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column

View file

@ -9,8 +9,6 @@ import androidx.navigation.NavController
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.faraphel.tasks_valider.ui.screen.communication.internet.client.CommunicationInternetClientScreen
import com.faraphel.tasks_valider.ui.screen.communication.internet.server.CommunicationInternetServerScreen
@Composable @Composable

View file

@ -1,4 +1,4 @@
package com.faraphel.tasks_valider.ui.screen.communication.internet.server package com.faraphel.tasks_valider.ui.screen.communication.internet
import android.app.Activity import android.app.Activity
import android.util.Log import android.util.Log
@ -19,7 +19,9 @@ import androidx.room.Room
import com.faraphel.tasks_valider.connectivity.task.TaskClient import com.faraphel.tasks_valider.connectivity.task.TaskClient
import com.faraphel.tasks_valider.connectivity.task.TaskServer import com.faraphel.tasks_valider.connectivity.task.TaskServer
import com.faraphel.tasks_valider.database.TaskDatabase import com.faraphel.tasks_valider.database.TaskDatabase
import com.faraphel.tasks_valider.database.entities.ClassEntity
import com.faraphel.tasks_valider.database.entities.PersonEntity import com.faraphel.tasks_valider.database.entities.PersonEntity
import com.faraphel.tasks_valider.database.populateTaskDatabaseTest
import com.faraphel.tasks_valider.ui.screen.authentification.AuthentificationServerScreen import com.faraphel.tasks_valider.ui.screen.authentification.AuthentificationServerScreen
import com.faraphel.tasks_valider.ui.screen.communication.DEFAULT_SERVER_PORT import com.faraphel.tasks_valider.ui.screen.communication.DEFAULT_SERVER_PORT
import com.faraphel.tasks_valider.ui.screen.communication.RANGE_SERVER_PORT import com.faraphel.tasks_valider.ui.screen.communication.RANGE_SERVER_PORT
@ -72,6 +74,7 @@ fun CommunicationInternetServerContent(
expanded = expandedStudentList.value, expanded = expandedStudentList.value,
onDismissRequest = { expandedStudentList.value = false } onDismissRequest = { expandedStudentList.value = false }
) { ) {
// TODO(Faraphel): student lists should be loaded from the database or a file
DropdownMenuItem( DropdownMenuItem(
text = { Text("ISRI") }, text = { Text("ISRI") },
onClick = {} onClick = {}
@ -80,7 +83,6 @@ fun CommunicationInternetServerContent(
text = { Text("MIAGE") }, text = { Text("MIAGE") },
onClick = {} onClick = {}
) )
// TODO(Faraphel): student lists should be loaded from the database or a file
} }
// server port // server port
@ -107,6 +109,10 @@ fun CommunicationInternetServerContent(
"local" "local"
).build() ).build()
// Populate the database with test data
// TODO(Faraphel): remove test data
populateTaskDatabaseTest(database)
// Insert the admin in the database // Insert the admin in the database
database.personDao().insert(adminPersonEntity) database.personDao().insert(adminPersonEntity)

View file

@ -1,67 +0,0 @@
package com.faraphel.tasks_valider.ui.screen.task
import android.app.Activity
import android.widget.Toast
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import com.faraphel.tasks_valider.connectivity.task.TaskClient
import com.faraphel.tasks_valider.connectivity.task.session.TaskSession
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
/**
* This screen represent a session
* @param activity the android activity
* @param client an HTTP client that can communicate with the server
*/
@Composable
fun TaskSessionScreen(activity: Activity, client: TaskClient) {
Text("WIP : Session Screen")
val session = remember { mutableStateOf<TaskSession?>(null) }
if (session.value == null)
return Thread { refreshGroups(activity, client, session) }.start()
Text("Session: ${session.value!!}")
/*
val students = remember { mutableStateOf<List<TaskGroupEntity>?>(null) }
// title
Text(text = "Task Group")
// if the groups are not yet defined, refresh the list
if (groups.value == null) {
Thread { refreshGroups(activity, client, groups) }.start()
return
}
// if the groups have already been defined, display them
for (group in groups.value!!) {
Text(text = group.toString())
}
*/
}
fun refreshGroups(activity: Activity, client: TaskClient, session: MutableState<TaskSession?>) {
val jsonParser = Gson()
// try to obtain the list of groups
val response = client.get("sessions/self")
// in case of error, notify it
if (!response.isSuccessful)
return activity.runOnUiThread { Toast.makeText(activity, response.message, Toast.LENGTH_LONG).show() }
// parse the list of groups
session.value = jsonParser.fromJson(
response.body.string(),
object : TypeToken<TaskSession>(){}.type
)
}

View file

@ -0,0 +1,63 @@
package com.faraphel.tasks_valider.ui.screen.task
import android.app.Activity
import android.widget.Toast
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import com.faraphel.tasks_valider.connectivity.task.TaskClient
import com.faraphel.tasks_valider.database.entities.PersonEntity
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
/**
* This screen represent a session
* @param activity the android activity
* @param client an HTTP client that can communicate with the server
*/
@Composable
fun TaskSessionScreen(activity: Activity, client: TaskClient) {
val students = remember { mutableStateOf<List<PersonEntity>?>(null) }
val selected_student = remember { mutableStateOf<PersonEntity?>(null) }
// if the groups are not yet defined, refresh the list
if (students.value == null)
return Thread { refreshStudents(activity, client, students) }.start()
if (selected_student.value != null)
return TaskStudentScreen(selected_student.value!!)
Column {
// if the groups have already been defined, display them
for (student in students.value!!) {
Button(onClick = { selected_student.value = student }) {
Text(text = student.fullName())
}
}
}
}
// TODO(Faraphel): template this function ?
fun refreshStudents(activity: Activity, client: TaskClient, students: MutableState<List<PersonEntity>?>) {
// TODO(Faraphel): global variable ?
val jsonParser = Gson()
// try to obtain the list of groups
val response = client.get("entities/" + PersonEntity.TABLE_NAME)
// in case of error, notify it
if (!response.isSuccessful)
return activity.runOnUiThread { Toast.makeText(activity, response.message, Toast.LENGTH_LONG).show() }
// parse the list of groups
students.value = jsonParser.fromJson(
response.body.string(),
object : TypeToken<List<PersonEntity>>(){}.type
)
}

View file

@ -0,0 +1,14 @@
package com.faraphel.tasks_valider.ui.screen.task
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import com.faraphel.tasks_valider.database.entities.PersonEntity
/**
* This screen represent a student
* @param student the student object
*/
@Composable
fun TaskStudentScreen(student: PersonEntity) {
Text(text = student.fullName())
}