core/client/src/jsMain/kotlin/dev/inmo/postssystem/client/utils/HTMLViewContainer.kt

135 lines
3.9 KiB
Kotlin

package dev.inmo.postssystem.client.utils
import kotlinx.browser.document
import kotlinx.dom.clear
import kotlinx.html.dom.append
import kotlinx.html.id
import kotlinx.html.js.*
import org.w3c.dom.HTMLElement
import org.w3c.dom.events.Event
object HTMLViewsConstants {
val mainContainer: MainHTMLViewContainer = MainHTMLViewContainer
val processesContainer: DrawerHTMLViewContainer = DrawerHTMLViewContainer
val toolsContainerId: ToolsHTMLViewContainer = ToolsHTMLViewContainer
}
sealed interface HTMLViewContainer {
val htmlElement: HTMLElement?
get() = document.getElementById(id) as? HTMLElement
val id: String
fun setIsLoading() {
htmlElement ?.apply {
clear()
append {
div("mdl-spinner mdl-js-spinner is-active")
}
}
}
companion object {
fun from(elementId: String) = when (elementId) {
MainHTMLViewContainer.id -> MainHTMLViewContainer
DrawerHTMLViewContainer.id -> DrawerHTMLViewContainer
ToolsHTMLViewContainer.id -> ToolsHTMLViewContainer
else -> null
}
}
}
object MainHTMLViewContainer : HTMLViewContainer {
override val id: String
get() = "main"
}
object DrawerHTMLViewContainer : HTMLViewContainer {
data class DrawerAddButtonInfo(
val text: String,
val onAddButtonClick: (Event) -> Unit,
)
override val id: String
get() = "drawer"
private val titleElement: HTMLElement?
get() = (document.getElementById("drawerTitle") ?:let {
htmlElement ?.append {
span("mdl-layout-title") {
id = "drawerTitle"
}
} ?.first()
}) as? HTMLElement
var title: String?
get() = titleElement ?.textContent
set(value) {
if (value == null) {
titleElement ?.classList ?.add("gone")
} else {
val element = titleElement ?: return
element.textContent = value
element.classList.remove("gone")
}
}
private val contentElement
get() = (document.getElementById("drawerContent") ?:let {
htmlElement ?.append {
nav("mdl-navigation") {
id = "drawerContent"
}
} ?.first()
}) as? HTMLElement
fun <T> setListContent(
title: String?,
data: Iterable<T>,
getText: (T) -> String?,
addButtonInfo: DrawerAddButtonInfo? = null,
onClick: (T) -> Unit
) {
this.title = title
val contentElement = contentElement ?: return
contentElement.clear()
contentElement.append {
fun hideDrawer() {
// Emulate clicking for hiding of drawer
(document.getElementsByClassName("mdl-layout__obfuscator").item(0) as? HTMLElement) ?.click()
}
data.forEach {
val elementTitle = getText(it) ?: return@forEach
div("mdl-navigation__link") {
+elementTitle
onClickFunction = { _ ->
onClick(it)
hideDrawer()
}
}
}
if (addButtonInfo != null) {
button(classes = "mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent") {
+addButtonInfo.text
onClickFunction = {
addButtonInfo.onAddButtonClick(it)
hideDrawer()
}
}
}
}
}
override fun setIsLoading() {
contentElement ?.apply {
clear()
append {
div("mdl-spinner mdl-js-spinner is-active")
}
}
}
}
object ToolsHTMLViewContainer : HTMLViewContainer {
override val id: String
get() = "tools"
}