progress
This commit is contained in:
1 parent
d84861949f
commit
b6c68f5045
14 files changed
+289
-42
No files matched your search
@@ -14,7 +14,7 @@ koinAnnotations = "2.3.1"
|
||||
kotlin = "2.4.20"
|
||||
kotlinx-html = "0.12.0"
|
||||
kspPlugin = "2.3.12"
|
||||
logback = "1.6.5}"
|
||||
logback = "1.6.5"
|
||||
postgresql = "42.7.13"
|
||||
|
||||
[libraries]
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#auto generated
|
||||
#Fri Oct 09 01:13:32 CEST 2026
|
||||
build.number=533
|
||||
#Sun Oct 11 01:02:04 CEST 2026
|
||||
build.number=551
|
||||
@@ -4,13 +4,13 @@ import net.keinekekse.version.Version
|
||||
|
||||
object VERSION: Version {
|
||||
override val version = "0.2.0-alpha"
|
||||
override val fullVersion = "0.2.0-alpha+build.533"
|
||||
override val fullVersion = "0.2.0-alpha+build.551"
|
||||
override val major = 0
|
||||
override val minor = 2
|
||||
override val patch = 0
|
||||
override val preRelease = "alpha"
|
||||
override val buildMetadata = "build.533"
|
||||
override val buildDate = "2026-10-08T23:13:32.459638Z"
|
||||
override val buildMetadata = "build.551"
|
||||
override val buildDate = "2026-10-10T23:02:04.857293Z"
|
||||
override val displayName = "Application Server"
|
||||
override val copyright = "Copyright (c) 2026 Hartmut Bauer"
|
||||
override val name = "server"
|
||||
@@ -18,13 +18,13 @@ object VERSION: Version {
|
||||
}
|
||||
object VERSION_books: Version {
|
||||
override val version = "0.2.0-alpha"
|
||||
override val fullVersion = "0.2.0-alpha+build.533"
|
||||
override val fullVersion = "0.2.0-alpha+build.551"
|
||||
override val major = 0
|
||||
override val minor = 2
|
||||
override val patch = 0
|
||||
override val preRelease = "alpha"
|
||||
override val buildMetadata = "build.533"
|
||||
override val buildDate = "2026-10-08T23:13:32.459742Z"
|
||||
override val buildMetadata = "build.551"
|
||||
override val buildDate = "2026-10-10T23:02:04.857387Z"
|
||||
override val displayName = "Books-DB"
|
||||
override val copyright = "Copyright (c) 2026 Hartmut Bauer"
|
||||
override val name = "books"
|
||||
|
||||
@@ -16,6 +16,7 @@ import kotlinx.html.p
|
||||
import kotlinx.html.span
|
||||
import net.keinekekse.app.books.db.BookRepository
|
||||
import net.keinekekse.app.books.db.CalibreBookInfoRepositoryImpl
|
||||
import net.keinekekse.app.books.db.schema.emptyBook
|
||||
import net.keinekekse.app.books.scan.getCover
|
||||
import net.keinekekse.app.books.scan.getIsbnFromCalibre
|
||||
import net.keinekekse.app.books.ui.*
|
||||
@@ -52,7 +53,7 @@ fun Application.configureRouting(
|
||||
call.application.log.info("OidcToken.Id.Principal userId: ${pp?.userInfo?.preferredUsername}")
|
||||
|
||||
call.respondHtml {
|
||||
testPage(db)
|
||||
booksPage(booksRepo)
|
||||
}
|
||||
}
|
||||
log.info(" ### Books page done")
|
||||
@@ -102,11 +103,14 @@ fun Application.configureRouting(
|
||||
}
|
||||
|
||||
// Edit
|
||||
get(navBooksEdit.second) {
|
||||
// TODO
|
||||
get("${navBooksEdit.second}/{id}") {
|
||||
val id = call.parameters["id"]?.toInt() ?: 0
|
||||
val book = booksRepo.bookById(id) ?: emptyBook()
|
||||
call.respondHtml { bookEditPage(book, booksRepo) }
|
||||
}
|
||||
|
||||
hx.post(navBooksEdit.second) {
|
||||
call.application.log.info("Edit book")
|
||||
call.application.log.info("Edit book form OK")
|
||||
call.receiveParameters().forEach { param: String, value: List<String> ->
|
||||
call.application.log.info("param: $param, value: $value")
|
||||
}
|
||||
@@ -117,6 +121,7 @@ fun Application.configureRouting(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hx.get("/isbnlookupreset") {
|
||||
// call.respondHtmlPartial(HttpStatusCode.OK) {
|
||||
// p { +"Bitte Barcode vor die Kamera halten..." }
|
||||
@@ -132,6 +137,13 @@ fun Application.configureRouting(
|
||||
// status = HttpStatusCode.OK
|
||||
// )
|
||||
// }
|
||||
|
||||
// Test-Page
|
||||
get("/books/test") {
|
||||
call.respondHtml {
|
||||
testPage(db)
|
||||
}
|
||||
}
|
||||
// "hx." lässt den Aufruf nur per HTMX zu. Der Pfad kann nicht
|
||||
// direkt im Browser aufgerufen werden.
|
||||
hx.get("/books/testdb") {
|
||||
@@ -161,7 +173,7 @@ fun Application.configureRouting(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Test 401
|
||||
authenticateWith(
|
||||
keycloakSession,
|
||||
@@ -172,6 +184,6 @@ fun Application.configureRouting(
|
||||
call.respondText("Test")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -12,11 +12,13 @@ object BooksTable : IntIdTable("books") {
|
||||
var originalTitle = varchar("original_title", 150).nullable()
|
||||
var year = integer("year")
|
||||
var originalYear = integer("original_year").nullable()
|
||||
var language = varchar("language", 2)
|
||||
var language = integer("language")
|
||||
var isbn = varchar("isbn", 13).index()
|
||||
var publisher = reference("publisher_id", PublisherTable.id)
|
||||
var series = optReference("series_id", SeriesTable.id)
|
||||
var seriesIndex = integer("seriesIndex").nullable()
|
||||
var type = integer("type")
|
||||
var read = bool("read").default(false)
|
||||
var comments = varchar("comments", 255)
|
||||
var parentBook = optReference("parent_book_id", id)
|
||||
val cover = blob("cover").nullable()
|
||||
@@ -31,9 +33,13 @@ class BookDAO(id: EntityID<Int>) : IntEntity(id) {
|
||||
var originalTitle by BooksTable.originalTitle
|
||||
var year by BooksTable.year
|
||||
var originalYear by BooksTable.originalYear
|
||||
var language: Languages by BooksTable.language.transform({ it.name }, { Languages.valueOf(it) })
|
||||
var language: Languages by BooksTable.language.transform(
|
||||
{ it.ordinal },
|
||||
{ Languages.entries[it] })
|
||||
var isbn by BooksTable.isbn
|
||||
var publisher by PublisherDAO.Companion referencedOn BooksTable.publisher
|
||||
var type by BooksTable.type.transform({ it.ordinal }, { BookType.entries[it] })
|
||||
var read by BooksTable.read
|
||||
var comments by BooksTable.comments
|
||||
var cover by BooksTable.cover
|
||||
|
||||
@@ -58,6 +64,8 @@ fun bookDaoToModel(dao: BookDAO, includeChildren: Boolean = true): Book = Book(
|
||||
dao.language,
|
||||
dao.isbn,
|
||||
publisher = Publisher(dao.publisher.id.value, dao.publisher.name),
|
||||
dao.type,
|
||||
dao.read,
|
||||
dao.comments,
|
||||
cover = dao.cover?.bytes ?: ByteArray(0),
|
||||
|
||||
|
||||
@@ -7,4 +7,8 @@ data class Artist(
|
||||
val id: Int = 0,
|
||||
val name: String = "",
|
||||
val givenName: String = "",
|
||||
)
|
||||
) {
|
||||
override fun toString(): String {
|
||||
return "$name $givenName"
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@ data class Book(
|
||||
val language: Languages = Languages.DE,
|
||||
val isbn: String = "",
|
||||
val publisher: Publisher,
|
||||
val type: BookType = BookType.BUCH,
|
||||
val read: Boolean = false,
|
||||
val comments: String = "",
|
||||
val cover: ByteArray = byteArrayOf(0),
|
||||
val series: Series? = null,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.keinekekse.app.books.model
|
||||
|
||||
enum class BookType {
|
||||
BUCH,
|
||||
COMIC,
|
||||
`E-BOOK`,
|
||||
`E-COMIC`
|
||||
}
|
||||
@@ -22,6 +22,7 @@ fun FlowContent.bookEdit(book: Book, booksRepo: BookRepository) {
|
||||
booksRepo.allTags()
|
||||
}
|
||||
|
||||
var tabCount = 1
|
||||
div(classes = "flex flex-col m-8") {
|
||||
form {
|
||||
attributes.hx {
|
||||
@@ -31,44 +32,62 @@ fun FlowContent.bookEdit(book: Book, booksRepo: BookRepository) {
|
||||
}
|
||||
|
||||
div(classes = "flex flex-row mb-5 h-9") {
|
||||
div(classes = "w-30 ") {
|
||||
div(classes = "w-30 content-center") {
|
||||
+"Typ"
|
||||
}
|
||||
select(classes = "$cssTextInput w-40") {
|
||||
name = "type"
|
||||
tabIndex = tabCount++.toString()
|
||||
|
||||
for (type in BookType.entries) {
|
||||
option {
|
||||
if (type == book.type)
|
||||
selected = true
|
||||
value = type.ordinal.toString()
|
||||
+type.name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
div(classes = "flex flex-row mb-5 h-9") {
|
||||
div(classes = "w-30 content-center") {
|
||||
+"Titel:"
|
||||
}
|
||||
input(classes = "$cssTextInput w-150") {
|
||||
name = "title"
|
||||
tabIndex = "1"
|
||||
tabIndex = tabCount++.toString()
|
||||
value = book.title
|
||||
}
|
||||
|
||||
}
|
||||
div(classes = "flex flex-row mb-5 h-9") {
|
||||
div(classes = "w-30 ") {
|
||||
div(classes = "w-30 content-center") {
|
||||
+"Originaltitel:"
|
||||
}
|
||||
input(classes = "$cssTextInput w-150") {
|
||||
name = "originaltitle"
|
||||
tabIndex = "2"
|
||||
tabIndex = tabCount++.toString()
|
||||
value = book.originalTitle ?: ""
|
||||
}
|
||||
|
||||
}
|
||||
div(classes = "flex flex-row mb-5 h-9") {
|
||||
div(classes = "w-30 ") {
|
||||
div(classes = "w-30 content-center") {
|
||||
+"Untertitel:"
|
||||
}
|
||||
input(classes = "$cssTextInput w-150") {
|
||||
name = "subtitle"
|
||||
tabIndex = "3"
|
||||
tabIndex = tabCount++.toString()
|
||||
value = book.subTitle ?: ""
|
||||
}
|
||||
}
|
||||
div(classes = "flex flex-row mb-5 h-9") {
|
||||
div(classes = "w-30") {
|
||||
div(classes = "w-30 content-center") {
|
||||
+"Sprache"
|
||||
}
|
||||
select(classes = "$cssTextInput w-16") {
|
||||
name = "language"
|
||||
tabIndex = "4"
|
||||
tabIndex = tabCount++.toString()
|
||||
|
||||
for (language in Languages.entries) {
|
||||
option {
|
||||
@@ -80,41 +99,41 @@ fun FlowContent.bookEdit(book: Book, booksRepo: BookRepository) {
|
||||
}
|
||||
}
|
||||
|
||||
div(classes = "ml-9 pr-3 ") {
|
||||
div(classes = "ml-9 pr-3 content-center") {
|
||||
+"Erscheinungsjahr:"
|
||||
}
|
||||
input(classes = "$cssTextInput w-16") {
|
||||
name = "year"
|
||||
tabIndex = "5"
|
||||
tabIndex = tabCount++.toString()
|
||||
value = book.year.toString()
|
||||
}
|
||||
|
||||
div(classes = "ml-8 pr-3") {
|
||||
div(classes = "ml-8 pr-3 content-center") {
|
||||
+"Jahr der Originalausgabe:"
|
||||
}
|
||||
input(classes = "$cssTextInput w-16") {
|
||||
name = "originalyear"
|
||||
tabIndex = "6"
|
||||
tabIndex = tabCount++.toString()
|
||||
value = book.originalYear?.toString() ?: ""
|
||||
}
|
||||
|
||||
}
|
||||
div(classes = "flex flex-row mb-5 h-9") {
|
||||
div(classes = "w-30") {
|
||||
div(classes = "w-30 content-center") {
|
||||
+"ISBN"
|
||||
}
|
||||
input(classes = "$cssTextInput w-40") {
|
||||
name = "isbn"
|
||||
tabIndex = "7"
|
||||
tabIndex = tabCount++.toString()
|
||||
value = book.isbn
|
||||
}
|
||||
|
||||
div(classes = "ml-14 pr-3") {
|
||||
div(classes = "ml-14 pr-3 content-center") {
|
||||
+"Verlag"
|
||||
}
|
||||
select(classes = "$cssTextInput w-74") {
|
||||
name = "publisher"
|
||||
tabIndex = "8"
|
||||
tabIndex = tabCount++.toString()
|
||||
|
||||
option {
|
||||
value = "0"
|
||||
@@ -130,7 +149,7 @@ fun FlowContent.bookEdit(book: Book, booksRepo: BookRepository) {
|
||||
}
|
||||
}
|
||||
a(classes = cssFormIcon) {
|
||||
tabIndex = "9"
|
||||
tabIndex = tabCount++.toString()
|
||||
title = "Verlag hinzufügen"
|
||||
materialSymbolFormButton("add_box")
|
||||
}
|
||||
@@ -138,12 +157,12 @@ fun FlowContent.bookEdit(book: Book, booksRepo: BookRepository) {
|
||||
}
|
||||
|
||||
div(classes = "flex flex-row mb-5 h-9") {
|
||||
div(classes = "w-30") {
|
||||
div(classes = "w-30 content-center") {
|
||||
+"Serie"
|
||||
}
|
||||
select(classes = "$cssTextInput w-98") {
|
||||
name = "series"
|
||||
tabIndex = "10"
|
||||
tabIndex = tabCount++.toString()
|
||||
|
||||
option {
|
||||
value = "0"
|
||||
@@ -159,22 +178,68 @@ fun FlowContent.bookEdit(book: Book, booksRepo: BookRepository) {
|
||||
}
|
||||
}
|
||||
a(classes = cssFormIcon) {
|
||||
tabIndex = "11"
|
||||
tabIndex = tabCount++.toString()
|
||||
title = "Serie hinzufügen"
|
||||
materialSymbolFormButton("add_box")
|
||||
}
|
||||
|
||||
div(classes = "ml-13 pr-3 ") {
|
||||
div(classes = "ml-13 pr-3 content-center") {
|
||||
+"Index"
|
||||
}
|
||||
input(classes = "$cssTextInput w-16") {
|
||||
name = "seriesindex"
|
||||
tabIndex = "12"
|
||||
tabIndex = tabCount++.toString()
|
||||
value = book.seriesIndex?.toString() ?: ""
|
||||
}
|
||||
}
|
||||
|
||||
div(classes = "flex flex-row mb-5 h-9") {
|
||||
div(classes = "flex flex-row mb-5") {
|
||||
div(classes = "w-30 content-center") {
|
||||
+"Künstler"
|
||||
}
|
||||
div(classes = "overflow-auto px-1 pb-1 h-40") {
|
||||
table {
|
||||
thead(classes = "$cssFixedTHead ") {
|
||||
tr {
|
||||
th(classes = "py-3 px-2") { +"Name" }
|
||||
th(classes = "py-3 px-2") { +"Rolle" }
|
||||
th(classes = "py-3 px-2") {
|
||||
a(classes = cssFormIcon) {
|
||||
tabIndex = tabCount++.toString()
|
||||
title = "Künstler hinzufügen"
|
||||
materialSymbolFormButton("add_box")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
|
||||
for ((artist, role) in book.artists) {
|
||||
tr {
|
||||
td(classes = "border-t-1 $borderTable px-2 py-1") {
|
||||
+"${artist.name}, ${artist.givenName}"
|
||||
}
|
||||
td(classes = "border-t-1 $borderTable px-2 py-1") {
|
||||
+role.role
|
||||
}
|
||||
td(classes = "border-t-1 $borderTable px-2 py-1") {
|
||||
a(classes = cssFormIcon) {
|
||||
tabIndex = tabCount++.toString()
|
||||
// href = "${navBooksEdit.second}/${book.id}"
|
||||
materialSymbolFormButton("Edit")
|
||||
}
|
||||
a(classes = cssFormIcon) {
|
||||
tabIndex = tabCount++.toString()
|
||||
materialSymbolFormButton("Delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// artists tags
|
||||
// | | | |
|
||||
// | | | |
|
||||
@@ -190,7 +255,7 @@ fun FlowContent.bookEdit(book: Book, booksRepo: BookRepository) {
|
||||
|
||||
|
||||
button(classes = "$cssButtonPri block mt-8") {
|
||||
tabIndex = "20"
|
||||
tabIndex = tabCount++.toString()
|
||||
type = ButtonType.submit
|
||||
+"Save"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package net.keinekekse.app.books.ui
|
||||
|
||||
import kotlinx.html.HTML
|
||||
import net.keinekekse.app.books.db.BookRepository
|
||||
import net.keinekekse.app.books.model.Book
|
||||
|
||||
fun HTML.bookEditPage(book: Book, booksRepo: BookRepository) {
|
||||
|
||||
booksPage(
|
||||
navBooksEdit.first,
|
||||
mapOf(navBooks, Pair(navBooksEdit.first, ""))
|
||||
) {
|
||||
|
||||
bookEdit(book, booksRepo)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package net.keinekekse.app.books.ui
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.html.*
|
||||
import net.keinekekse.app.books.db.BookRepository
|
||||
import net.keinekekse.app.books.model.Book
|
||||
|
||||
fun HTML.booksPage(booksRepo: BookRepository) {
|
||||
booksPage("Books-DB", mapOf(Pair(navBooks.first, ""))) {
|
||||
// content left
|
||||
div(classes = "basis-64 px-1 py-2 text-center $bgLeftColumn") {
|
||||
div {
|
||||
+"some content on the left "
|
||||
}
|
||||
|
||||
}
|
||||
// content right
|
||||
div(classes = "flex flex-auto $bgRightColumn") {
|
||||
div(classes = "flex flex-col flex-auto") {
|
||||
// div {
|
||||
// +"some heading"
|
||||
// }
|
||||
booksTable(booksRepo)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun FlowContent.booksTable(booksRepo: BookRepository) {
|
||||
val books: List<Book> = runBlocking {
|
||||
booksRepo.allBooks()
|
||||
}
|
||||
|
||||
div(classes = "flex-auto overflow-auto px-1 pb-1") {
|
||||
table {
|
||||
id = "bookstable"
|
||||
thead(classes = "$cssFixedTHead ") {
|
||||
tr {
|
||||
th(classes = "py-3 px-2") { +"Titel" }
|
||||
th(classes = "py-3 px-2") { +"Autor(en)" }
|
||||
th(classes = "py-3 px-2") { +"Serie" }
|
||||
th(classes = "py-3 px-2") { +"Sprache" }
|
||||
th(classes = "py-3 px-2") { +"Jahr" }
|
||||
th(classes = "py-3 px-2") { +"Typ" }
|
||||
th(classes = "py-3 px-2") { +"Gelesen" }
|
||||
th(classes = "py-3 px-2") {
|
||||
a {
|
||||
href = navBooksNew.second
|
||||
title = navBooksNew.first
|
||||
materialSymbolButton(
|
||||
"auto_stories",
|
||||
"font-weight: bold; font-size: 2em"
|
||||
)
|
||||
// library_add
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
for (book in books) {
|
||||
tr {
|
||||
td(classes = "border-t-1 $borderTable px-2 py-1") {
|
||||
+book.title
|
||||
}
|
||||
td(classes = "border-t-1 $borderTable px-2 py-1") {
|
||||
+artistsString(book, 40)
|
||||
}
|
||||
td(classes = "border-t-1 $borderTable px-2 py-1") {
|
||||
+(book.series?.name ?: "") // TODO add index
|
||||
}
|
||||
td(classes = "border-t-1 $borderTable px-2 py-1") {
|
||||
+book.language.name
|
||||
}
|
||||
td(classes = "border-t-1 $borderTable px-2 py-1") {
|
||||
+book.year.toString()
|
||||
}
|
||||
td(classes = "border-t-1 $borderTable px-2 py-1") {
|
||||
+book.type.name
|
||||
}
|
||||
td(classes = "border-t-1 $borderTable px-2 py-1 text-center text-slate-400") {
|
||||
title = if (book.read) "gelesen" else "ungelesen"
|
||||
if (book.read) materialSymbol("check_small") //check_small || check_circle
|
||||
else materialSymbol("close_small") //cancel || close || block
|
||||
}
|
||||
td(classes = "border-t-1 $borderTable px-2 py-1 text-nowrap") {
|
||||
a {
|
||||
title = if (book.read) "ungelesen" else "gelesen"
|
||||
materialSymbolButton("published_with_changes")
|
||||
}
|
||||
a {
|
||||
href = "${navBooksEdit.second}/${book.id}"
|
||||
materialSymbolButton("Edit")
|
||||
}
|
||||
materialSymbolButton("Delete")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun artistsString(book: Book, len: Int = 0): String {
|
||||
val rc = book.artists.joinToString(" & ") { it.artist.toString() }
|
||||
return if (rc.length > len) rc.slice(0..len) else rc
|
||||
}
|
||||
@@ -51,6 +51,7 @@ fun HTML.booksPage(title: String, breadcrumbs: Map<String, String>, block: DIV.(
|
||||
programName()
|
||||
div(classes = "ml-10 flex self-end pr-5 pt-2 border-t-1 items-baseline") {
|
||||
a(classes = cssHeaderLink) {
|
||||
tabIndex = "0"
|
||||
href = "/"
|
||||
materialSymbol("home")
|
||||
// +"Start"
|
||||
@@ -60,6 +61,7 @@ fun HTML.booksPage(title: String, breadcrumbs: Map<String, String>, block: DIV.(
|
||||
breadcrumbs.forEach { (name, url) ->
|
||||
if (url.isNotEmpty()) {
|
||||
a(classes = cssHeaderLink) {
|
||||
tabIndex = "0"
|
||||
href = url
|
||||
+name
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.keinekekse.app.books.ui
|
||||
import io.ktor.util.logging.*
|
||||
import net.keinekekse.app.books.db.BookRepository
|
||||
import net.keinekekse.app.books.db.schema.*
|
||||
import net.keinekekse.app.books.model.BookType
|
||||
import net.keinekekse.app.books.model.Languages
|
||||
import org.jetbrains.exposed.v1.jdbc.Database
|
||||
import org.jetbrains.exposed.v1.jdbc.SchemaUtils
|
||||
@@ -85,6 +86,8 @@ suspend fun dbTest(db: Database, booksRepo: BookRepository) {
|
||||
language = Languages.EN
|
||||
isbn = "9781617296823"
|
||||
publisher = pub1
|
||||
type = BookType.BUCH
|
||||
read = true
|
||||
comments = ""
|
||||
}
|
||||
val kp = BookDAO.new {
|
||||
@@ -97,6 +100,7 @@ suspend fun dbTest(db: Database, booksRepo: BookRepository) {
|
||||
language = Languages.EN
|
||||
isbn = "9781617298823"
|
||||
publisher = pub2
|
||||
type = BookType.BUCH
|
||||
comments = ""
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.keinekekse.app.core.ui
|
||||
|
||||
import io.ktor.htmx.html.*
|
||||
import io.ktor.util.logging.*
|
||||
import io.ktor.utils.io.*
|
||||
import kotlinx.html.*
|
||||
@@ -50,6 +51,18 @@ fun HTML.landingPage(loggedOn: Boolean) {
|
||||
}
|
||||
}
|
||||
div(classes = "m-8") {
|
||||
button(classes = cssMainLink) {
|
||||
id = "testDB"
|
||||
attributes.hx {
|
||||
get = "/books/testdb"
|
||||
// target = "#testdb"
|
||||
// swap = HxSwap.innerHtml
|
||||
// trigger = "click"
|
||||
}
|
||||
+"Create DB"
|
||||
}
|
||||
}
|
||||
div(classes = "m-8") {
|
||||
// a(classes = "p-2 font-bold text-sky-500 hover:text-sky-700 hover:bg-cyan-100 cursor-pointer") {
|
||||
// href = "/oidc/keycloak/login"
|
||||
// +"Login"
|
||||
|
||||
Reference in new issue
Block a user