mirror of
https://github.com/smyalygames/checklist-tester.git
synced 2026-01-01 17:28:47 +01:00
feat(connector): link projects to database
This commit is contained in:
@@ -10,6 +10,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import cafe.adriel.voyager.core.screen.Screen
|
import cafe.adriel.voyager.core.screen.Screen
|
||||||
|
import cafe.adriel.voyager.koin.getScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ class CreateProject : Screen {
|
|||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
|
val screenModel = getScreenModel<ProjectsScreenModel>()
|
||||||
|
|
||||||
var projectName by remember { mutableStateOf("") }
|
var projectName by remember { mutableStateOf("") }
|
||||||
var aircraftType by remember { mutableStateOf("") }
|
var aircraftType by remember { mutableStateOf("") }
|
||||||
@@ -61,9 +63,14 @@ class CreateProject : Screen {
|
|||||||
Button(
|
Button(
|
||||||
contentPadding = ButtonDefaults.ButtonWithIconContentPadding,
|
contentPadding = ButtonDefaults.ButtonWithIconContentPadding,
|
||||||
onClick = {
|
onClick = {
|
||||||
// TODO save new project and make sure it redirects to list page
|
if (projectName.isNotBlank() and aircraftType.isNotBlank()) {
|
||||||
|
screenModel.createProject(
|
||||||
|
projectName = projectName,
|
||||||
|
aircraftType = aircraftType
|
||||||
|
)
|
||||||
navigator.pop()
|
navigator.pop()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Outlined.Add, "Create Project", modifier = Modifier.size(18.dp))
|
Icon(Icons.Outlined.Add, "Create Project", modifier = Modifier.size(18.dp))
|
||||||
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
|
Spacer(Modifier.size(ButtonDefaults.IconSpacing))
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Column
|
|||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.rememberScrollbarAdapter
|
import androidx.compose.foundation.rememberScrollbarAdapter
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
@@ -19,8 +20,9 @@ import androidx.compose.ui.Modifier
|
|||||||
import cafe.adriel.voyager.core.screen.Screen
|
import cafe.adriel.voyager.core.screen.Screen
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
|
import io.anthonyberg.connector.shared.entity.Project
|
||||||
|
|
||||||
class ListProjects : Screen {
|
class ListProjects(private val projects: List<Project>) : Screen {
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
@@ -45,20 +47,8 @@ class ListProjects : Screen {
|
|||||||
modifier = Modifier.fillMaxWidth(0.7F),
|
modifier = Modifier.fillMaxWidth(0.7F),
|
||||||
) {
|
) {
|
||||||
LazyColumn(state = state) {
|
LazyColumn(state = state) {
|
||||||
items(50) { index ->
|
items(projects) { project ->
|
||||||
ListItem(
|
projectItem(project)
|
||||||
modifier = Modifier
|
|
||||||
.clickable(
|
|
||||||
enabled = true,
|
|
||||||
onClick = {
|
|
||||||
// TODO add loading project
|
|
||||||
}
|
|
||||||
),
|
|
||||||
overlineContent = { Text("Boeing 737-800") },
|
|
||||||
headlineContent = { Text("Project $index") },
|
|
||||||
trailingContent = { Icon(Icons.AutoMirrored.Filled.KeyboardArrowRight, "Open Project") }
|
|
||||||
)
|
|
||||||
HorizontalDivider()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VerticalScrollbar(
|
VerticalScrollbar(
|
||||||
@@ -73,4 +63,22 @@ class ListProjects : Screen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun projectItem(project: Project) {
|
||||||
|
ListItem(
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable(
|
||||||
|
enabled = true,
|
||||||
|
onClick = {
|
||||||
|
// TODO add loading project
|
||||||
|
}
|
||||||
|
),
|
||||||
|
overlineContent = { Text(project.aircraftType) },
|
||||||
|
headlineContent = { Text(project.name) },
|
||||||
|
trailingContent = { Icon(Icons.AutoMirrored.Filled.KeyboardArrowRight, "Open Project") }
|
||||||
|
)
|
||||||
|
HorizontalDivider()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
package tab.project
|
package tab.project
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import cafe.adriel.voyager.koin.getScreenModel
|
import cafe.adriel.voyager.koin.getScreenModel
|
||||||
import cafe.adriel.voyager.navigator.Navigator
|
import cafe.adriel.voyager.navigator.Navigator
|
||||||
import cafe.adriel.voyager.navigator.tab.Tab
|
import cafe.adriel.voyager.navigator.tab.Tab
|
||||||
@@ -36,11 +33,14 @@ class Projects : Tab {
|
|||||||
val screenModel = getScreenModel<ProjectsScreenModel>()
|
val screenModel = getScreenModel<ProjectsScreenModel>()
|
||||||
val state by screenModel.state.collectAsState()
|
val state by screenModel.state.collectAsState()
|
||||||
|
|
||||||
when (state) {
|
when (val s = state) {
|
||||||
is ProjectsScreenModel.State.UnInit -> screenModel.projectExists()
|
is ProjectState.Init -> Navigator(NoProjects())
|
||||||
is ProjectsScreenModel.State.Init -> Navigator(NoProjects())
|
is ProjectState.Loading -> Navigator(LoadingScreen("Projects"))
|
||||||
is ProjectsScreenModel.State.Loading -> Navigator(LoadingScreen("Projects"))
|
is ProjectState.Result -> Navigator(ListProjects(s.projects))
|
||||||
is ProjectsScreenModel.State.Result -> Navigator(ListProjects())
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(currentCompositeKeyHash) {
|
||||||
|
screenModel.projectExists()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,33 +8,44 @@ import kotlinx.coroutines.launch
|
|||||||
|
|
||||||
class ProjectsScreenModel (
|
class ProjectsScreenModel (
|
||||||
private val db: ProjectTransaction
|
private val db: ProjectTransaction
|
||||||
) : StateScreenModel<ProjectsScreenModel.State>(State.UnInit) {
|
) : StateScreenModel<ProjectState>(ProjectState.Loading) {
|
||||||
|
|
||||||
sealed class State {
|
|
||||||
object UnInit : State()
|
|
||||||
object Init : State()
|
|
||||||
object Loading : State()
|
|
||||||
data class Result(val projects: List<Project>) : State()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun projectExists() {
|
fun projectExists() {
|
||||||
screenModelScope.launch {
|
screenModelScope.launch {
|
||||||
mutableState.value = State.Loading
|
|
||||||
val exists = db.projectExists()
|
val exists = db.projectExists()
|
||||||
|
|
||||||
if (exists) {
|
if (exists) {
|
||||||
getProjects()
|
val projects = getProjects()
|
||||||
|
mutableState.value = ProjectState.Result(projects = projects)
|
||||||
} else {
|
} else {
|
||||||
mutableState.value = State.Init
|
mutableState.value = ProjectState.Init
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getProjects() {
|
private fun getProjects(): List<Project> {
|
||||||
mutableState.value = State.Loading
|
|
||||||
val projects = db.getProjects()
|
val projects = db.getProjects()
|
||||||
|
println(projects)
|
||||||
|
|
||||||
mutableState.value = State.Result(projects)
|
return projects
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createProject(projectName : String, aircraftType : String) {
|
||||||
|
screenModelScope.launch {
|
||||||
|
mutableState.value = ProjectState.Loading
|
||||||
|
|
||||||
|
// Add project to database
|
||||||
|
db.createProject(projectName = projectName, aircraftType = aircraftType)
|
||||||
|
|
||||||
|
// Load new projects
|
||||||
|
val projects = getProjects()
|
||||||
|
mutableState.value = ProjectState.Result(projects = projects)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class ProjectState {
|
||||||
|
data object Init : ProjectState()
|
||||||
|
data object Loading : ProjectState()
|
||||||
|
data class Result(val projects: List<Project>) : ProjectState()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io.anthonyberg.connector.shared
|
|||||||
import io.anthonyberg.connector.shared.database.DriverFactory
|
import io.anthonyberg.connector.shared.database.DriverFactory
|
||||||
import io.anthonyberg.connector.shared.database.ProjectDatabase
|
import io.anthonyberg.connector.shared.database.ProjectDatabase
|
||||||
import io.anthonyberg.connector.shared.entity.Project
|
import io.anthonyberg.connector.shared.entity.Project
|
||||||
|
import kotlinx.datetime.Clock
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All database transactions for Project
|
* All database transactions for Project
|
||||||
@@ -13,8 +14,10 @@ class ProjectTransaction (driverFactory: DriverFactory) {
|
|||||||
/**
|
/**
|
||||||
* Creates a project in the database.
|
* Creates a project in the database.
|
||||||
*/
|
*/
|
||||||
fun createProject(project: Project) {
|
fun createProject(projectName: String, aircraftType: String) {
|
||||||
database.createProject(project)
|
val currentTime = Clock.System.now().toString()
|
||||||
|
|
||||||
|
database.createProject(name = projectName, aircraftType = aircraftType, createdUTC = currentTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -32,11 +32,11 @@ internal class ProjectDatabase (driverFactory: DriverFactory) {
|
|||||||
/**
|
/**
|
||||||
* Inserts a project into the database
|
* Inserts a project into the database
|
||||||
*/
|
*/
|
||||||
internal fun createProject(project: Project) {
|
internal fun createProject(name: String, aircraftType: String, createdUTC: String) {
|
||||||
dbQuery.createProject(
|
dbQuery.createProject(
|
||||||
name = project.name,
|
name = name,
|
||||||
aircraftType = project.aircraftType,
|
aircraftType = aircraftType,
|
||||||
createdUTC = project.createdUTC,
|
createdUTC = createdUTC,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user