Skip to content

Commit

Permalink
Fix todo table (#184)
Browse files Browse the repository at this point in the history
Co-authored-by: hfhbd <[email protected]>
  • Loading branch information
hfhbd and hfhbd authored May 5, 2021
1 parent 11c3208 commit 090f7b3
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 83 deletions.
108 changes: 54 additions & 54 deletions backend/src/jvmMain/kotlin/app/softwork/composetodo/TodoModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -71,75 +71,75 @@ fun Application.TodoModule(db: Database, jwtProvider: JWTProvider) {
jwtProvider.token(user)
}
}
}
authenticate {
route("/refreshToken") {
delete {
call.sessions.clear<RefreshToken>()
call.respond(HttpStatusCode.OK)
}
}

authenticate {
route("/refreshToken") {
delete {
call.sessions.clear<RefreshToken>()
call.respond(HttpStatusCode.OK)
route("/me") {
get {
call.respondJson(User.serializer()) {
call.principal<app.softwork.composetodo.dao.User>()!!.toDTO()
}
}

route("/me") {
get {
call.respondJson(User.serializer()) {
call.principal<app.softwork.composetodo.dao.User>()!!.toDTO()
}
put {
call.respondJson(User.serializer()) {
val user = call.principal<app.softwork.composetodo.dao.User>()!!
val toUpdate = body(User.serializer())
UserController(user).update(toUpdate)
}
put {
call.respondJson(User.serializer()) {
val user = call.principal<app.softwork.composetodo.dao.User>()!!
val toUpdate = body(User.serializer())
UserController(user).update(toUpdate)
}
}
delete {
with(call) {
val user = call.principal<app.softwork.composetodo.dao.User>()!!
TodoController(user).deleteAll()
UserController(user).delete()
respond(HttpStatusCode.OK)
}
delete {
with(call) {
val user = call.principal<app.softwork.composetodo.dao.User>()!!
TodoController(user).deleteAll()
UserController(user).delete()
respond(HttpStatusCode.OK)
}
}
}

route("/todos") {
get {
call.respondJsonList(Todo.serializer()) {
val user = call.principal<app.softwork.composetodo.dao.User>()!!
TodoController(user).todos()
}
}
post {
call.respondJson(Todo.serializer()) {
val user = call.principal<app.softwork.composetodo.dao.User>()!!
val newTodo = body(Todo.serializer())
TodoController(user).create(newTodo)
}
}
route("/todos") {

route("/{todoID}") {
get {
call.respondJsonList(Todo.serializer()) {
call.respondJson(Todo.serializer()) {
val user = call.principal<app.softwork.composetodo.dao.User>()!!
TodoController(user).todos()
val todoID: UUID by parameters
TodoController(user).getTodo(todoID)
}
}
post {
put {
call.respondJson(Todo.serializer()) {
val user = call.principal<app.softwork.composetodo.dao.User>()!!
val newTodo = body(Todo.serializer())
TodoController(user).create(newTodo)
val todoID: UUID by parameters
val toUpdate = body(Todo.serializer())
TodoController(user).update(todoID, toUpdate)
}
}

route("/todoID") {
get("/{todoID}") {
call.respondJson(Todo.serializer()) {
val user = call.principal<app.softwork.composetodo.dao.User>()!!
val todoID: UUID by parameters
TodoController(user).getTodo(todoID)
}
}
put {
call.respondJson(Todo.serializer()) {
val user = call.principal<app.softwork.composetodo.dao.User>()!!
val todoID: UUID by parameters
val toUpdate = body(Todo.serializer())
TodoController(user).update(todoID, toUpdate)
}
}
delete {
with(call) {
val user = call.principal<app.softwork.composetodo.dao.User>()!!
val todoID: UUID by parameters
TodoController(user).delete(todoID)
respond(HttpStatusCode.OK)
}
delete {
with(call) {
val user = call.principal<app.softwork.composetodo.dao.User>()!!
val todoID: UUID by parameters
TodoController(user).delete(todoID)
respond(HttpStatusCode.OK)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class TodoController(val user: User) {

suspend fun create(newTodo: app.softwork.composetodo.dto.Todo) = newSuspendedTransaction {
Todo.new(newTodo.id) {
this.user = user
this.user = this@TodoController.user
title = newTodo.title
until = newTodo.until?.toJavaLocalDateTime()
finished = newTodo.finished
Expand Down
72 changes: 52 additions & 20 deletions client-core/src/jsMain/kotlin/app/softwork/composetodo/Bootstrap.kt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,32 @@ fun Container(
content()
}

@Composable
inline fun DateTimeInput(
label: String,
labelClasses: String = "form-label",
inputClasses: String = "form-control",
placeholder: String,
value: String,
crossinline attrs: AttrsBuilder<Tag.Input>.() -> Unit = { },
crossinline onChange: (HTMLInputElement) -> Unit
) = Label(forId = "", attrs = {
classes(labelClasses)
attr("for", null)
}) {
Text(label)
Input(type = InputType.DateTimeLocal, attrs = {
attrs()
classes(inputClasses)
value(value)
placeholder(placeholder)
addEventListener("input") {
onChange(it.nativeEvent.target as HTMLInputElement)
}
})
}


@Composable
inline fun input(
type: InputType = InputType.Text,
Expand All @@ -102,23 +128,18 @@ inline fun input(
classes(labelClasses)
attr("for", null)
}) {
require(type != InputType.DateTimeLocal)
Text(label)
Input(type = type, attrs = {
attrs()
classes(inputClasses)
value(value)
placeholder(placeholder)
this.onInput {
val target = (it.nativeEvent.target as? HTMLInputElement) ?: return@onInput println(jsTypeOf(it.nativeEvent.target))
val target = it.nativeEvent.target as HTMLInputElement
onChange(target)
}
})

Input(type = InputType.DateTimeLocal, attrs = {
onInput {
val event = it.nativeEvent
}
})
}


Expand All @@ -141,10 +162,10 @@ inline fun button(
Text(title)
}

data class Row(val id: String, val color: Color?, val cells: List<Cell>) {
data class Row(val color: Color?, val cells: List<Cell>) {
data class Cell(val color: Color?, val content: @Composable () -> Unit)

class Builder(val id: String) {
class Builder {
private val values = mutableListOf<Pair<String, Cell>>()

var rowColor: Color? = null
Expand Down Expand Up @@ -231,7 +252,7 @@ private inline fun td(
content: @Composable ElementScope<HTMLTableCellElement>.() -> Unit
) {
TagElement(
tagName = "th",
tagName = "td",
applyAttrs = attrs,
applyStyle = style,
content = content
Expand All @@ -256,7 +277,7 @@ private inline fun tbody(

@Composable
fun <T> Table(
data: List<T>, id: (T) -> String,
data: List<T>,
color: Color? = null,
striped: Boolean = false,
hover: Boolean = false,
Expand All @@ -266,15 +287,15 @@ fun <T> Table(
val rows = mutableListOf<Row>()

data.forEach {
val row = Row.Builder(id(it)).apply { map(it) }
val row = Row.Builder().apply { map(it) }
val (rowValues, rowColor) = row.build()
val cells = rowValues.map { (header, cellValue) ->
if (header !in headers) {
headers.add(header)
}
cellValue
}
val row1 = Row(row.id, rowColor, cells)
val row1 = Row(rowColor, cells)
rows.add(row1)
}
Table(
Expand All @@ -295,11 +316,16 @@ fun Table(
rows: List<Row>
) {
table(attrs = {
classes(
"table",
color?.let { "table-$it" } ?: "",
"table-hover".takeIf { hover } ?: "",
"table-striped".takeIf { striped } ?: "")
classes {
+"table"
color?.let { +"table-$it" }
if (hover) {
+"table-hover"
}
if (striped) {
+"table-striped"
}
}
}) {
thead {
tr {
Expand All @@ -315,10 +341,16 @@ fun Table(
tbody {
for (row in rows) {
tr(attrs = {
classes("table${row.color?.let { "-$it" }}")
classes {
row.color?.let { +"table-$it" }
}
}) {
for (cell in row.cells) {
td(attrs = { classes("table${cell.color?.let { "-$it" }}") }) {
td(attrs = {
classes {
cell.color?.let { +"table-$it" }
}
}) {
cell.content()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package app.softwork.composetodo.login

import androidx.compose.runtime.*
import androidx.compose.web.attributes.*
import androidx.compose.web.elements.*
import androidx.compose.web.elements.Text
import app.softwork.composetodo.*
import kotlinx.coroutines.*

Expand All @@ -11,6 +13,9 @@ fun Login(api: API.LoggedOut, onLogin: (API.LoggedIn) -> Unit) {
var password by mutableStateOf("")
Row {
Column {
H1 {
Text("Login")
}
input(value = username, placeholder = "user.name", label = "Username") {
username = it.value
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package app.softwork.composetodo.login

import androidx.compose.runtime.*
import androidx.compose.web.attributes.*
import androidx.compose.web.elements.*
import androidx.compose.web.elements.Text
import app.softwork.composetodo.*
import app.softwork.composetodo.dto.*
import kotlinx.coroutines.*
Expand All @@ -16,6 +18,9 @@ fun Register(api: API.LoggedOut, onLogin: (API.LoggedIn) -> Unit) {

Row {
Column {
H1 {
Text("Register")
}
input(value = username, placeholder = "user.name", label = "Username") {
username = it.value
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app.softwork.composetodo.todos

import androidx.compose.runtime.*
import androidx.compose.web.attributes.*
import androidx.compose.web.elements.*
import app.softwork.composetodo.*
import app.softwork.composetodo.dto.*
import kotlinx.coroutines.*
Expand All @@ -13,10 +14,7 @@ class NewTodoViewModel(val api: API.LoggedIn, val onDone: () -> Unit) {
var until by mutableStateOf("")

val disabledButton: Boolean
get() {
println("disabledButton $title $until s")
return title.isEmpty() || until.isEmpty()
}
get() = title.isEmpty() || until.isEmpty()

fun createTodo() {
scope.launch {
Expand All @@ -38,16 +36,17 @@ fun NewTodo(viewModel: NewTodoViewModel) {
input(type = InputType.Text, label = "Title", placeholder = "Hello World", value = viewModel.title) {
viewModel.title = it.value
}
input(
type = InputType.DateTimeLocal,
DateTimeInput(
label = "Finish Date",
placeholder = "yyyy-mm-dd",
value = viewModel.until
) {
viewModel.until = it.value
}
button("Create new Todo", attrs = {
disabled(viewModel.disabledButton)
if(viewModel.disabledButton) {
disabled(true)
}
}) {
viewModel.createTodo()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ import kotlinx.datetime.*
class TodosViewModel(val api: API.LoggedIn) {
var todos by mutableStateOf(emptyList<Todo>())

init {
scope.launch {
todos = api.getTodos()
}
}

fun refresh() {
scope.launch {
todos = api.getTodos()
Expand All @@ -33,7 +39,7 @@ fun Todos(viewModel: TodosViewModel) {
if (viewModel.todos.isEmpty()) {
Text("No Todos created")
} else {
Table(viewModel.todos, { it.id.toString() }) { todo ->
Table(viewModel.todos) { todo ->
rowColor = when {
todo.finished -> Color.Success
todo.until?.let {
Expand Down

0 comments on commit 090f7b3

Please sign in to comment.