Trash feature done
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
package be.simplenotes.app.views
|
||||
|
||||
import be.simplenotes.app.utils.StaticFileResolver
|
||||
import be.simplenotes.app.views.components.Alert
|
||||
import be.simplenotes.app.views.components.alert
|
||||
import be.simplenotes.app.views.components.submitButton
|
||||
import be.simplenotes.app.views.components.*
|
||||
import be.simplenotes.domain.model.PersistedNote
|
||||
import be.simplenotes.domain.model.PersistedNoteMetadata
|
||||
import be.simplenotes.domain.security.JwtPayload
|
||||
@@ -53,41 +51,57 @@ class NoteView(staticFileResolver: StaticFileResolver) : View(staticFileResolver
|
||||
notes: List<PersistedNoteMetadata>,
|
||||
currentPage: Int,
|
||||
numberOfPages: Int,
|
||||
tag: String?
|
||||
) =
|
||||
renderPage(title = "Notes", jwtPayload = jwtPayload) {
|
||||
div("container mx-auto p-4") {
|
||||
div("flex justify-between mb-4") {
|
||||
h1("text-2xl underline") { +"Notes" }
|
||||
tag: String?,
|
||||
) = renderPage(title = "Notes", jwtPayload = jwtPayload) {
|
||||
div("container mx-auto p-4") {
|
||||
div("flex justify-between mb-4") {
|
||||
h1("text-2xl underline") { +"Notes" }
|
||||
span {
|
||||
a(
|
||||
href = "/notes/trash",
|
||||
classes = "underline font-semibold"
|
||||
) { +"Trash" }
|
||||
a(
|
||||
href = "/notes/new",
|
||||
classes = "btn btn-green"
|
||||
classes = "ml-2 btn btn-green"
|
||||
) { +"New" }
|
||||
}
|
||||
if (notes.isNotEmpty()) {
|
||||
|
||||
ul {
|
||||
notes.forEach { (title, tags, _, uuid) ->
|
||||
li("flex justify-between") {
|
||||
a(classes = "text-blue-200 text-xl hover:underline", href = "/notes/$uuid") {
|
||||
+title
|
||||
}
|
||||
span("space-x-2") {
|
||||
tags.forEach {
|
||||
a(href = "?tag=$it", classes = "tag") {
|
||||
+"#$it"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (numberOfPages > 1)
|
||||
pagination(currentPage, numberOfPages, tag)
|
||||
} else
|
||||
span { +"No notes yet" } // FIXME if too far in pagination, it it displayed
|
||||
}
|
||||
if (notes.isNotEmpty())
|
||||
noteTable(notes)
|
||||
else
|
||||
span {
|
||||
if (numberOfPages > 1) +"You went too far"
|
||||
else +"No notes yet"
|
||||
}
|
||||
|
||||
if (numberOfPages > 1) pagination(currentPage, numberOfPages, tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun trash(
|
||||
jwtPayload: JwtPayload,
|
||||
notes: List<PersistedNoteMetadata>,
|
||||
currentPage: Int,
|
||||
numberOfPages: Int
|
||||
) = renderPage(title = "Notes", jwtPayload = jwtPayload) {
|
||||
div("container mx-auto p-4") {
|
||||
div("flex justify-between mb-4") {
|
||||
h1("text-2xl underline") { +"Deleted notes" }
|
||||
}
|
||||
if (notes.isNotEmpty())
|
||||
deletedNoteTable(notes)
|
||||
else
|
||||
span {
|
||||
if (numberOfPages > 1) +"You went too far"
|
||||
else +"No deleted notes"
|
||||
}
|
||||
|
||||
if (numberOfPages > 1) pagination(currentPage, numberOfPages, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun DIV.pagination(currentPage: Int, numberOfPages: Int, tag: String?) {
|
||||
val links = mutableListOf<Pair<String, String>>()
|
||||
|
||||
@@ -14,7 +14,7 @@ abstract class View(private val staticFileResolver: StaticFileResolver) {
|
||||
title: String,
|
||||
description: String? = null,
|
||||
jwtPayload: JwtPayload?,
|
||||
body: BODY.() -> Unit = {},
|
||||
body: MAIN.() -> Unit = {},
|
||||
) = buildString {
|
||||
appendLine("<!DOCTYPE html>")
|
||||
appendHTML().html {
|
||||
@@ -29,7 +29,7 @@ abstract class View(private val staticFileResolver: StaticFileResolver) {
|
||||
}
|
||||
body("bg-gray-900 text-white") {
|
||||
navbar(jwtPayload)
|
||||
main { this@body.body() }
|
||||
main { body() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package be.simplenotes.app.views.components
|
||||
|
||||
import be.simplenotes.domain.model.PersistedNoteMetadata
|
||||
import kotlinx.html.*
|
||||
import kotlinx.html.ButtonType.submit
|
||||
import kotlinx.html.FormMethod.post
|
||||
import kotlinx.html.ThScope.col
|
||||
import org.http4k.core.Method
|
||||
|
||||
fun FlowContent.deletedNoteTable(notes: List<PersistedNoteMetadata>) = div("overflow-x-auto") {
|
||||
table {
|
||||
id = "notes"
|
||||
thead {
|
||||
tr {
|
||||
th(col, "w-1/4") { +"Title" }
|
||||
th(col, "w-1/4") { +"Updated" }
|
||||
th(col, "w-1/4") { +"Tags" }
|
||||
th(col, "w-1/4") { +"Restore" }
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
notes.forEach { (title, tags, updatedAt, uuid) ->
|
||||
tr {
|
||||
td { +title }
|
||||
td("text-center") { +updatedAt.toString() } // TODO: x time ago
|
||||
td { tags(tags) }
|
||||
td("text-center") {
|
||||
form(classes = "inline", method = post, action = "/notes/deleted/$uuid") {
|
||||
button(classes = "btn btn-red", type = submit, name = "delete") {
|
||||
+"Delete permanently"
|
||||
}
|
||||
button(classes = "ml-2 btn btn-green", type = submit, name = "restore") {
|
||||
+"Restore"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FlowContent.tags(tags: List<String>) {
|
||||
ul("inline flex flex-wrap justify-center") {
|
||||
tags.forEach { tag ->
|
||||
li("mx-2 my-1") {
|
||||
span("tag") { +"#$tag" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,14 @@ import be.simplenotes.domain.security.JwtPayload
|
||||
import kotlinx.html.*
|
||||
|
||||
fun BODY.navbar(jwtPayload: JwtPayload?) {
|
||||
nav("nav bg-teal-700 shadow-md flex items-center justify-between px-4") {
|
||||
a(href = "/", classes = "text-2xl text-gray-100 font-bold") { +"SimpleNotes" }
|
||||
nav {
|
||||
id = "navbar"
|
||||
a("/") {
|
||||
id = "home"
|
||||
+"SimpleNotes"
|
||||
}
|
||||
ul("space-x-2") {
|
||||
id = "navigation"
|
||||
if (jwtPayload != null) {
|
||||
val links = listOf(
|
||||
"/notes" to "Notes",
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package be.simplenotes.app.views.components
|
||||
|
||||
import be.simplenotes.domain.model.PersistedNoteMetadata
|
||||
import kotlinx.html.*
|
||||
import kotlinx.html.ThScope.col
|
||||
|
||||
fun FlowContent.noteTable(notes: List<PersistedNoteMetadata>) = div("overflow-x-auto") {
|
||||
table {
|
||||
id = "notes"
|
||||
thead {
|
||||
tr {
|
||||
th(col, "w-1/2") { +"Title" }
|
||||
th(col, "w-1/4") { +"Updated" }
|
||||
th(col, "w-1/4") { +"Tags" }
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
notes.forEach { (title, tags, updatedAt, uuid) ->
|
||||
tr {
|
||||
td {
|
||||
a(classes = "text-blue-200 font-semibold underline", href = "/notes/$uuid") { +title }
|
||||
}
|
||||
td("text-center") { +updatedAt.toString() } // TODO: x time ago
|
||||
td { tags(tags) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FlowContent.tags(tags: List<String>) {
|
||||
ul("inline flex flex-wrap justify-center") {
|
||||
tags.forEach { tag ->
|
||||
li("mx-2 my-1") {
|
||||
a(href = "?tag=$tag", classes = "tag") { +"#$tag" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user