425 lines
16 KiB
Kotlin
425 lines
16 KiB
Kotlin
package net.keinekekse.app.books.ui
|
|
|
|
import io.ktor.htmx.html.*
|
|
import kotlinx.coroutines.runBlocking
|
|
import kotlinx.html.*
|
|
import net.keinekekse.app.books.db.BookRepository
|
|
import net.keinekekse.app.books.edit.BooksSessionData
|
|
import net.keinekekse.app.books.model.BookType
|
|
import net.keinekekse.app.books.model.Languages
|
|
import net.keinekekse.app.core.auth.UserSession
|
|
|
|
fun FlowContent.bookEdit(
|
|
booksRepo: BookRepository,
|
|
session: UserSession<BooksSessionData>,
|
|
) {
|
|
|
|
session.data.publisherList = runBlocking {
|
|
booksRepo.allPublishers()
|
|
}
|
|
session.data.seriesList = runBlocking {
|
|
booksRepo.allSeries()
|
|
}
|
|
session.data.artistList = runBlocking {
|
|
booksRepo.allArtists()
|
|
}
|
|
session.data.tagList = runBlocking {
|
|
booksRepo.allTags()
|
|
}
|
|
|
|
div(classes = "flex flex-col m-8") {
|
|
form {
|
|
attributes.hx {
|
|
post = navBooksEdit.second
|
|
target = "#response"
|
|
swap = "innerHTML"
|
|
}
|
|
input(type = InputType.hidden, name = "sessionId") {
|
|
value = session.sessionId
|
|
}
|
|
input(type = InputType.hidden, name = "bookId") {
|
|
value = session.data.book.id.toString()
|
|
}
|
|
|
|
div(classes = "flex flex-row mb-5 h-9") {
|
|
div(classes = "w-30 content-center") {
|
|
+"Typ"
|
|
}
|
|
select(classes = "$cssTextInput w-40") {
|
|
name = "type"
|
|
autoFocus = true
|
|
|
|
for (type in BookType.entries) {
|
|
option {
|
|
if (type == session.data.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"
|
|
value = session.data.book.title
|
|
}
|
|
|
|
}
|
|
div(classes = "flex flex-row mb-5 h-9") {
|
|
div(classes = "w-30 content-center") {
|
|
+"Originaltitel"
|
|
}
|
|
input(classes = "$cssTextInput w-150") {
|
|
name = "originaltitle"
|
|
value = session.data.book.originalTitle ?: ""
|
|
}
|
|
|
|
}
|
|
div(classes = "flex flex-row mb-5 h-9") {
|
|
div(classes = "w-30 content-center") {
|
|
+"Untertitel"
|
|
}
|
|
input(classes = "$cssTextInput w-150") {
|
|
name = "subtitle"
|
|
value = session.data.book.subTitle ?: ""
|
|
}
|
|
}
|
|
div(classes = "flex flex-row mb-5 h-9") {
|
|
div(classes = "w-30 content-center") {
|
|
+"Sprache"
|
|
}
|
|
select(classes = "$cssTextInput w-16") {
|
|
name = "language"
|
|
|
|
for (language in Languages.entries) {
|
|
option {
|
|
if (language == session.data.book.language)
|
|
selected = true
|
|
value = language.ordinal.toString()
|
|
+language.name
|
|
}
|
|
}
|
|
}
|
|
|
|
div(classes = "w-45 pr-3 content-center text-end") {
|
|
+"Erscheinungsjahr"
|
|
}
|
|
input(classes = "$cssTextInput w-16") {
|
|
name = "year"
|
|
value = session.data.book.year.toString()
|
|
}
|
|
|
|
div(classes = "w-57 pr-3 content-center text-end") {
|
|
+"Jahr der Originalausgabe"
|
|
}
|
|
input(classes = "$cssTextInput w-16") {
|
|
name = "originalyear"
|
|
value = session.data.book.originalYear?.toString() ?: ""
|
|
}
|
|
|
|
}
|
|
div(classes = "flex flex-row mb-5 h-9") {
|
|
div(classes = "w-32 content-center") {
|
|
+"ISBN"
|
|
}
|
|
input(classes = "$cssTextInput w-40") {
|
|
name = "isbn"
|
|
value = session.data.book.isbn
|
|
}
|
|
|
|
div(classes = "w-26 pr-3 content-center text-end") {
|
|
+"Verlag"
|
|
}
|
|
select(classes = "$cssTextInput w-74") {
|
|
name = "publisher"
|
|
id = "publisher"
|
|
|
|
option {
|
|
value = "0"
|
|
+"---"
|
|
}
|
|
for (pub in session.data.publisherList) {
|
|
option {
|
|
if (pub.id == session.data.book.publisher.id)
|
|
selected = true
|
|
value = pub.id.toString()
|
|
+pub.name
|
|
}
|
|
}
|
|
}
|
|
button(classes = cssFormIcon) {
|
|
title = "Verlag hinzufügen"
|
|
// TODO
|
|
/*
|
|
type = ButtonType.button -> sonst wird "submit" angenommen und dann funktioniert
|
|
es nicht!
|
|
*/
|
|
type = ButtonType.button
|
|
// attributes["popovertarget"] = "publisherDialog"
|
|
// onClick = "document.getElementById('publisherDialog').showModal()"
|
|
attributes["command"] = "show-modal"
|
|
attributes["commandfor"] = "publisherDialog" //id
|
|
|
|
materialSymbolFormButton("add_box")
|
|
}
|
|
|
|
}
|
|
|
|
div(classes = "flex flex-row mb-5 h-9") {
|
|
div(classes = "w-30 content-center") {
|
|
+"Serie"
|
|
}
|
|
select(classes = "$cssTextInput w-100") {
|
|
name = "series"
|
|
|
|
option {
|
|
value = "0"
|
|
+"---"
|
|
}
|
|
for (serie in session.data.seriesList) {
|
|
option {
|
|
if (session.data.book.series != null && serie.id == session.data.book.series!!.id)
|
|
selected = true
|
|
value = serie.id.toString()
|
|
+serie.name
|
|
}
|
|
}
|
|
}
|
|
button(classes = cssFormIcon) {
|
|
title = "Serie hinzufügen"
|
|
materialSymbolFormButton("add_box")
|
|
}
|
|
|
|
div(classes = "w-20 pr-3 content-center text-end") {
|
|
+"Index"
|
|
}
|
|
input(classes = "$cssTextInput w-20") {
|
|
name = "seriesindex"
|
|
value = session.data.book.seriesIndex?.toString() ?: ""
|
|
}
|
|
}
|
|
|
|
div(classes = "flex flex-row mb-7") {
|
|
div(classes = "w-30 content-start pt-3") {
|
|
+"Künstler"
|
|
}
|
|
div(classes = "overflow-auto px-1 pb-1 h-40 w-82") {
|
|
tabIndex = "-1" // overflow setzt sonst einen Tabstopp
|
|
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") {
|
|
// button(classes = cssFormIcon) {
|
|
// title = "Künstler hinzufügen"
|
|
// materialSymbolFormButton("add_box")
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
tbody {
|
|
|
|
for ((artist, role) in session.data.book.artists) {
|
|
tr {
|
|
td(classes = "border-b-1 $borderTable px-2 py-1") {
|
|
+"${artist.name}, ${artist.givenName}"
|
|
}
|
|
td(classes = "border-b-1 $borderTable px-2 py-1") {
|
|
+role.role
|
|
}
|
|
td(classes = "border-b-1 $borderTable px-2 py-1") {
|
|
button(classes = cssFormIcon) {
|
|
// href = "${navBooksEdit.second}/${book.id}"
|
|
materialSymbolFormButton("Edit")
|
|
}
|
|
button(classes = cssFormIcon) {
|
|
materialSymbolFormButton("Delete")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
button(classes = "$cssFormIcon self-start mt-2 ") {
|
|
title = "Künstler hinzufügen"
|
|
materialSymbolFormButton("add_box")
|
|
}
|
|
|
|
div(classes = "w-20 pr-3 content-start text-end pt-3") {
|
|
+"Tags"
|
|
}
|
|
div(classes = "overflow-auto px-1 pb-1 h-40 w-30") {
|
|
tabIndex = "-1" // overflow setzt sonst einen Tabstopp
|
|
table {
|
|
// thead(classes = "$cssFixedTHead ") {
|
|
// tr {
|
|
// th(classes = "py-3 px-2") { +"Tag" }
|
|
// th(classes = "py-3 px-2") {
|
|
// button(classes = cssFormIcon) {
|
|
// title = "Tag hinzufügen"
|
|
// materialSymbolFormButton("add_box")
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
tbody {
|
|
for (tag in session.data.book.tags) {
|
|
tr {
|
|
td(classes = "border-b-1 $borderTable px-2 py-1") {
|
|
+tag.tag
|
|
}
|
|
td(classes = "border-b-1 $borderTable px-2 py-1") {
|
|
button(classes = cssFormIcon) {
|
|
materialSymbolFormButton("Delete")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
button(classes = "$cssFormIcon self-start mt-2") {
|
|
title = "Tag hinzufügen"
|
|
materialSymbolFormButton("add_box")
|
|
}
|
|
|
|
}
|
|
|
|
div(classes = "flex flex-row mb-5") {
|
|
div(classes = "w-30 content-center") {
|
|
+"Kommentar"
|
|
}
|
|
textArea(classes = "$cssTextInput w-150 h-18 resize-none") {
|
|
name = "comment"
|
|
spellCheck = true
|
|
+session.data.book.comments
|
|
}
|
|
}
|
|
// TODO parent
|
|
// evtl. switch oder <detail>
|
|
// Teil von Sammelband _____v / enthält (-> Link)
|
|
div(classes = "flex flex-row mb-5 h-9") {
|
|
div(classes = "w-30 content-center") {
|
|
+"Sammelband"
|
|
}
|
|
label(
|
|
classes = "w-10 justify-center grid grid-cols-[1.3em] " +
|
|
"focus-within:bg-orange-300 hover:bg-orange-300"
|
|
) {
|
|
input {
|
|
name = "sampler"
|
|
type = InputType.checkBox // liefert sampler=on || nix !
|
|
checked = session.data.book.isSampler
|
|
}
|
|
}
|
|
div(classes = "w-30 content-center text-end pr-3") {
|
|
+"Teil von"
|
|
}
|
|
select(classes = "$cssTextInput w-50") {
|
|
name = "parent"
|
|
option {
|
|
value = "0"
|
|
+"---"
|
|
}
|
|
// for (serie in session.data.seriesList) {
|
|
// option {
|
|
// if (session.data.book.series != null && serie.id == session.data.book.series!!.id)
|
|
// selected = true
|
|
// value = serie.id.toString()
|
|
// +serie.name
|
|
// }
|
|
// }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
div(classes = "flex flex-row mb-5 mr-2 justify-end w-180") {
|
|
button(classes = "$cssButtonStd block mt-8 mr-10") {
|
|
type = ButtonType.button
|
|
onClick =
|
|
"window.history.back()"
|
|
+"Abbrechen"
|
|
}
|
|
button(classes = "$cssButtonPri block mt-8") {
|
|
type = ButtonType.submit
|
|
+"Speichern"
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO
|
|
dialog(
|
|
classes = "m-auto h-fit w-full max-w-md rounded-lg shadow-2xl border-2 " +
|
|
"$borderTable px-3 py-2 $bgBody $textBody $bgDialogBackdrop"
|
|
) {
|
|
id = "publisherDialog"
|
|
// attributes["popover"] = "true"
|
|
// attributes["closedby"] = "any"
|
|
form {
|
|
id = "publisherDialogForm"
|
|
attributes.hx {
|
|
post = "${navBooksEdit.second}/addpublisher"
|
|
target = "#publisher"
|
|
swap = "innerHTML"
|
|
validate = true
|
|
on(
|
|
event = "after-request",
|
|
script = "this.reset();document.getElementById('publisherDialog').close()"
|
|
)
|
|
}
|
|
input(type = InputType.hidden, name = "sessionId") {
|
|
value = session.sessionId
|
|
}
|
|
input(type = InputType.hidden, name = "bookId") {
|
|
value = session.data.book.id.toString()
|
|
}
|
|
|
|
div(classes = "flex flex-row mb-5 h-9") {
|
|
div(classes = "content-center pr-6 text-nowrap") {
|
|
+"Neuer Verlag:"
|
|
}
|
|
input(classes = "$cssTextInput w-75") {
|
|
name = "newpublisher"
|
|
required = true
|
|
value = ""
|
|
onBlur = """
|
|
const select = document.getElementById('publisher')
|
|
const optArray = Array.from(select.options)
|
|
if (optArray.some(opt => opt.text.toLowerCase() === this.value.toLowerCase() )) {
|
|
this.setCustomValidity('Dieser Verlag existiert bereits.');
|
|
} else {
|
|
this.setCustomValidity('');
|
|
}
|
|
"""
|
|
}
|
|
}
|
|
div(classes = "flex flex-row mb-5 mr-2 justify-end") {
|
|
button(classes = "$cssButtonStd block mt-8 mr-10") {
|
|
type = ButtonType.button
|
|
onClick =
|
|
"document.getElementById('publisherDialogForm').reset()"
|
|
attributes["commandfor"] = "publisherDialog"
|
|
attributes["command"] = "close"
|
|
+"Abbrechen"
|
|
}
|
|
button(classes = "$cssButtonPri block mt-8") {
|
|
type = ButtonType.submit
|
|
+"Speichern"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
output { }
|
|
div {
|
|
id = "response"
|
|
}
|
|
}
|
|
}
|