You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by jo...@apache.org on 2021/09/24 09:04:34 UTC
[isis] 03/03: ISIS-2872 Upgrade Kotlin/KVision Dependencies
This is an automated email from the ASF dual-hosted git repository.
joergrade pushed a commit to branch ISIS-2872
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 526eee54028d36389271c2a9fba8ca02d60fded8
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Fri Sep 24 11:01:54 2021 +0200
ISIS-2872 Upgrade Kotlin/KVision Dependencies
---
incubator/clients/kroviz/TODO.adoc | 11 ++
incubator/clients/kroviz/build.gradle.kts | 83 +++----------
incubator/clients/kroviz/gradle.properties | 8 +-
.../kotlin/org/apache/isis/client/kroviz/App.kt | 30 ++++-
.../isis/client/kroviz/ui/core/MenuFactory.kt | 102 +++++++++-------
.../org/apache/isis/client/kroviz/ui/core/RoApp.kt | 3 +-
.../apache/isis/client/kroviz/ui/core/RoDialog.kt | 76 ++++++------
.../apache/isis/client/kroviz/ui/core/RoMenuBar.kt | 67 ++++++-----
.../isis/client/kroviz/ui/core/RoStatusBar.kt | 31 ++---
.../apache/isis/client/kroviz/ui/core/RoTable.kt | 7 +-
.../isis/client/kroviz/ui/kv/override/RoTab.kt | 59 ++++-----
.../client/kroviz/ui/kv/override/RoTabPanel.kt | 132 +++++++++------------
.../isis/client/kroviz/ui/kv/override/RoWindow.kt | 9 +-
.../isis/client/kroviz/ui/panel/EventLogTable.kt | 2 -
14 files changed, 297 insertions(+), 323 deletions(-)
diff --git a/incubator/clients/kroviz/TODO.adoc b/incubator/clients/kroviz/TODO.adoc
new file mode 100644
index 0000000..ce1e295
--- /dev/null
+++ b/incubator/clients/kroviz/TODO.adoc
@@ -0,0 +1,11 @@
+# KVision
+
+* upgrade to 5.latest, kotlin to 1.5.10
+* revert patch to build.gradle.kts
+* https://github.com/rjaros/kvision/issues/306 (select in dropdown)
+* https://github.com/rjaros/kvision/issues/247 (map to fill whole container)
+* https://github.com/rjaros/kvision/issues/299 (header footer access)
+* Remove duplicated / copied KV files
+
+# Long Term
+* use docker for integration test
diff --git a/incubator/clients/kroviz/build.gradle.kts b/incubator/clients/kroviz/build.gradle.kts
index 455b821..5652244 100644
--- a/incubator/clients/kroviz/build.gradle.kts
+++ b/incubator/clients/kroviz/build.gradle.kts
@@ -16,15 +16,15 @@
// specific language governing permissions and limitations
// under the License.
//
-import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
-import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
plugins {
val kotlinVersion: String by System.getProperties()
- id("kotlinx-serialization") version kotlinVersion
+ kotlin("plugin.serialization") version kotlinVersion
kotlin("js") version kotlinVersion
+ val kvisionVersion: String by System.getProperties()
+ id("io.kvision") version kvisionVersion
}
version = "2.0.0-SNAPSHOT"
@@ -40,6 +40,7 @@ repositories {
val kotlinVersion: String by System.getProperties()
val kvisionVersion: String by System.getProperties()
+// Custom Properties
val webDir = file("src/main/web")
kotlin {
@@ -47,16 +48,13 @@ kotlin {
browser {
runTask {
outputFileName = "main.bundle.js"
- sourceMaps = true
+ sourceMaps = false
devServer = KotlinWebpackConfig.DevServer(
open = false,
port = 3000,
proxy = mutableMapOf(
"/kv/*" to "http://localhost:8080",
- "/kvws/*" to mapOf(
- "target" to "ws://localhost:8080",
- "ws" to true
- )
+ "/kvws/*" to mapOf("target" to "ws://localhost:8080", "ws" to true)
),
static = mutableListOf("$buildDir/processedResources/js/main")
)
@@ -73,15 +71,17 @@ kotlin {
binaries.executable()
}
sourceSets["main"].dependencies {
+ implementation(npm("react-awesome-button", "*"))
+ implementation(npm("prop-types", "*"))
implementation("io.kvision:kvision:$kvisionVersion")
implementation("io.kvision:kvision-bootstrap:$kvisionVersion")
- implementation("io.kvision:kvision-bootstrap:$kvisionVersion")
implementation("io.kvision:kvision-bootstrap-css:$kvisionVersion")
implementation("io.kvision:kvision-bootstrap-datetime:$kvisionVersion")
implementation("io.kvision:kvision-bootstrap-select:$kvisionVersion")
implementation("io.kvision:kvision-bootstrap-spinner:$kvisionVersion")
implementation("io.kvision:kvision-bootstrap-upload:$kvisionVersion")
implementation("io.kvision:kvision-bootstrap-dialog:$kvisionVersion")
+ implementation("io.kvision:kvision-bootstrap-typeahead:$kvisionVersion")
implementation("io.kvision:kvision-fontawesome:$kvisionVersion")
implementation("io.kvision:kvision-i18n:$kvisionVersion")
implementation("io.kvision:kvision-richtext:$kvisionVersion")
@@ -90,6 +90,11 @@ kotlin {
implementation("io.kvision:kvision-chart:$kvisionVersion")
implementation("io.kvision:kvision-tabulator:$kvisionVersion")
implementation("io.kvision:kvision-pace:$kvisionVersion")
+ implementation("io.kvision:kvision-toast:$kvisionVersion")
+ implementation("io.kvision:kvision-react:$kvisionVersion")
+ implementation("io.kvision:kvision-routing-navigo:$kvisionVersion")
+ implementation("io.kvision:kvision-state:$kvisionVersion")
+ implementation("io.kvision:kvision-rest:$kvisionVersion")
implementation("io.kvision:kvision-moment:$kvisionVersion")
implementation("io.kvision:kvision-maps:$kvisionVersion")
implementation(npm("xmltojson", "1.3.5", false))
@@ -101,63 +106,3 @@ kotlin {
}
sourceSets["main"].resources.srcDir(webDir)
}
-
-fun getNodeJsBinaryExecutable(): String {
- val nodeDir = NodeJsRootPlugin.apply(rootProject).nodeJsSetupTaskProvider.get().destination
- val isWindows = System.getProperty("os.name").toLowerCase().contains("windows")
- val nodeBinDir = if (isWindows) nodeDir else nodeDir.resolve("bin")
- val command = NodeJsRootPlugin.apply(rootProject).nodeCommand
- val finalCommand = if (isWindows && command == "node") "node.exe" else command
- return nodeBinDir.resolve(finalCommand).absolutePath
-}
-
-tasks {
- create("generatePotFile", Exec::class) {
- dependsOn("compileKotlinJs")
- executable = getNodeJsBinaryExecutable()
- args("${rootProject.buildDir}/js/node_modules/gettext-extract/bin/gettext-extract")
- inputs.files(kotlin.sourceSets["main"].kotlin.files)
- outputs.file("$projectDir/src/main/resources/i18n/messages.pot")
- }
-}
-afterEvaluate {
- extensions.configure<NodeJsRootExtension> {
- versions.webpackDevServer.version = "4.0.0"
- }
- tasks {
- getByName("processResources", Copy::class) {
- dependsOn("compileKotlinJs")
- exclude("**/*.pot")
- doLast("Convert PO to JSON") {
- destinationDir.walkTopDown().filter {
- it.isFile && it.extension == "po"
- }.forEach {
- exec {
- executable = getNodeJsBinaryExecutable()
- args(
- "${rootProject.buildDir}/js/node_modules/gettext.js/bin/po2json",
- it.absolutePath,
- "${it.parent}/${it.nameWithoutExtension}.json"
- )
- println("Converted ${it.name} to ${it.nameWithoutExtension}.json")
- }
- it.delete()
- }
- }
- }
- create("zip", Zip::class) {
- dependsOn("browserProductionWebpack")
- group = "package"
- destinationDirectory.set(file("$buildDir/libs"))
- val distribution =
- project.tasks.getByName("browserProductionWebpack", KotlinWebpack::class).destinationDirectory!!
- from(distribution) {
- include("*.*")
- }
- from(webDir)
- duplicatesStrategy = DuplicatesStrategy.EXCLUDE
- inputs.files(distribution, webDir)
- outputs.file(archiveFile)
- }
- }
-}
diff --git a/incubator/clients/kroviz/gradle.properties b/incubator/clients/kroviz/gradle.properties
index 1f665df..2ecbefd 100644
--- a/incubator/clients/kroviz/gradle.properties
+++ b/incubator/clients/kroviz/gradle.properties
@@ -18,8 +18,8 @@
#
javaVersion=1.8
#Plugins
-systemProp.kotlinVersion=1.5.10
-serializationVersion=1.2.1
+systemProp.kotlinVersion=1.5.31
+serializationVersion=1.2.2
#Dependencies
-systemProp.kvisionVersion=4.8.3
-kotlin.js.compiler=legacy
+systemProp.kvisionVersion=5.1.1
+kotlin.js.compiler=ir
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/App.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/App.kt
index 34a3976..316864b 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/App.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/App.kt
@@ -18,24 +18,28 @@
*/
package org.apache.isis.client.kroviz
+import io.kvision.*
import org.apache.isis.client.kroviz.ui.core.RoApp
-import io.kvision.Application
import io.kvision.pace.Pace
+import io.kvision.panel.ContainerType
import io.kvision.panel.root
import io.kvision.panel.vPanel
-import io.kvision.startApplication
import io.kvision.utils.px
-import io.kvision.require
+import kotlinx.browser.window
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.asCoroutineDispatcher
+
+val AppScope = CoroutineScope(window.asCoroutineDispatcher())
class App : Application() {
init {
+ Pace.init()
require("css/kroviz.css")
}
override fun start() {
- Pace.init()
- root("kroviz") {
+ root("kroviz", containerType = ContainerType.FLUID, addRow = true) {
vPanel(spacing = 0) {
padding = 0.px
add(RoApp)
@@ -49,5 +53,19 @@ class App : Application() {
}
fun main() {
- startApplication(::App)
+ startApplication(
+ ::App,
+ module.hot,
+ BootstrapModule,
+ BootstrapCssModule,
+ FontAwesomeModule,
+ BootstrapSelectModule,
+ BootstrapDatetimeModule,
+ BootstrapSpinnerModule,
+// BootstrapTypeaheadModule,
+ BootstrapUploadModule,
+ RichTextModule,
+ ChartModule,
+ TabulatorModule,
+ CoreModule)
}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/MenuFactory.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/MenuFactory.kt
index f34cc30..ef99b62 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/MenuFactory.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/MenuFactory.kt
@@ -36,17 +36,20 @@ import io.kvision.html.Link as KvisionHtmlLink
object MenuFactory {
- fun buildForObject(tObject: TObject,
- withText: Boolean = true,
- iconName: String = "Actions")
+ fun buildForObject(
+ tObject: TObject,
+ withText: Boolean = true,
+ iconName: String = "Actions"
+ )
: DropDown {
val type = tObject.domainType
val text = if (withText) "Actions for $type" else ""
val icon = IconManager.find(iconName)
val dd = DropDown(
- text = text,
- icon = icon,
- style = ButtonStyle.LINK)
+ text = text,
+ icon = icon,
+ style = ButtonStyle.LINK
+ )
val actions = tObject.getActions()
actions.forEach {
val link = buildActionLink(it.id, text)
@@ -59,18 +62,22 @@ object MenuFactory {
return dd
}
- fun buildForMenu(menu: Menu,
- style: ButtonStyle = ButtonStyle.LIGHT,
- withText: Boolean = true,
- classes: Set<String> = setOf())
+ fun buildForMenu(
+ menu: Menu,
+ style: ButtonStyle = ButtonStyle.LIGHT,
+ withText: Boolean = true,
+ classes: Set<String> = setOf()
+ )
: DropDown {
val menuTitle = menu.named
val dd = DropDown(
- text = if (withText) menuTitle else "",
- icon = IconManager.find(menuTitle),
- style = style,
- classes = classes,
- forNavbar = false)
+ text = if (withText) menuTitle else "",
+ icon = IconManager.find(menuTitle),
+ style = style,
+// classes = classes,
+ forNavbar = false
+ )
+ dd.addCssClass(classes.toString())
//dd.setDragDropData(Constants.stdMimeType, menuTitle)
// action.setDragDropData gets always overridden by dd.setDragDropData
menu.section.forEachIndexed { index, section ->
@@ -93,8 +100,9 @@ object MenuFactory {
val menu = findMenuByTitle(title)
return if (menu == null) null else
buildForMenu(
- menu = menu,
- withText = false)
+ menu = menu,
+ withText = false
+ )
}
private fun findMenuByTitle(menuTitle: String): Menu? {
@@ -110,8 +118,9 @@ object MenuFactory {
}
fun buildForAction(
- menuTitle: String,
- actionTitle: String): KvisionHtmlLink? {
+ menuTitle: String,
+ actionTitle: String
+ ): KvisionHtmlLink? {
val menu = findMenuByTitle(menuTitle)!!
menu.section.forEachIndexed { _, section ->
section.serviceAction.forEach { sa ->
@@ -129,14 +138,16 @@ object MenuFactory {
return null
}
- fun buildActionLink(
- label: String,
- menuTitle: String): KvisionHtmlLink {
+ fun buildActionLink(
+ label: String,
+ menuTitle: String
+ ): KvisionHtmlLink {
val actionTitle = StringUtils.deCamel(label)
val actionLink: KvisionHtmlLink = ddLink(
- label = actionTitle,
- icon = IconManager.find(label),
- classes = IconManager.findStyleFor(label))
+ label = actionTitle,
+ icon = IconManager.find(label),
+ classes = IconManager.findStyleFor(label)
+ )
val id = "$menuTitle${Constants.actionSeparator}$actionTitle"
actionLink.setDragDropData(Constants.stdMimeType, id)
actionLink.id = id
@@ -144,33 +155,37 @@ object MenuFactory {
}
private fun ddLink(
- label: String,
- icon: String? = null,
- classes: Set<String>? = null,
- init: (KvisionHtmlLink.() -> Unit)? = null
+ label: String,
+ icon: String? = null,
+ classes: Set<String>? = null,
+ init: (KvisionHtmlLink.() -> Unit)? = null
): KvisionHtmlLink {
- return KvisionHtmlLink(
- label = label,
- url = null,
- icon = icon,
- image = null,
- separator = null,
- labelFirst = true,
- classes = (classes ?: null.set) + "dropdown-item").apply {
+ val link = KvisionHtmlLink(
+ label = label,
+ url = null,
+ icon = icon,
+ image = null,
+ separator = null,
+ labelFirst = true
+ )
+ link.addCssClass("dropdown-item")
+ return link.apply {
init?.invoke(this)
}
}
// initially added items will be enabled
fun amendWithSaveUndo(
- dd: DropDown,
- tObject: TObject) {
+ dd: DropDown,
+ tObject: TObject
+ ) {
dd.separator()
val saveLink = tObject.links.first()
val saveAction = buildActionLink(
- label = "save",
- menuTitle = tObject.domainType)
+ label = "save",
+ menuTitle = tObject.domainType
+ )
saveAction.onClick {
ResourceProxy().fetch(saveLink)
}
@@ -178,8 +193,9 @@ object MenuFactory {
val undoLink = Link(href = "")
val undoAction = buildActionLink(
- label = "undo",
- menuTitle = tObject.domainType)
+ label = "undo",
+ menuTitle = tObject.domainType
+ )
undoAction.onClick {
ResourceProxy().fetch(undoLink)
}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoApp.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoApp.kt
index 067db26..eb6bba1 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoApp.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoApp.kt
@@ -27,9 +27,10 @@ object RoApp : SimplePanel() {
init {
this.add(RoMenuBar.navbar)
- val view = HPanel(classes = setOf("main")) {
+ val view = HPanel() {
width = CssSize(100, UNIT.perc)
}
+ view.addCssClass("main")
view.add(RoIconBar.panel)
view.add(RoView.tabPanel)
this.add(view)
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoDialog.kt
index b977975..ec579c1 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoDialog.kt
@@ -38,49 +38,54 @@ import org.apache.isis.client.kroviz.utils.Point
import io.kvision.html.Link as KvisionHtmlLink
class RoDialog(
- caption: String,
- val items: List<FormItem>,
- val command: Command,
- defaultAction: String = "OK",
- widthPerc: Int = 30,
- heightPerc: Int = 100,
- menu: List<KvisionHtmlLink>? = null,
- customButtons: List<FormItem> = emptyList() ) :
- Displayable, RoWindow(caption = caption, closeButton = true, menu = menu) {
+ caption: String,
+ val items: List<FormItem>,
+ val command: Command,
+ defaultAction: String = "OK",
+ widthPerc: Int = 30,
+ heightPerc: Int = 100,
+ menu: List<KvisionHtmlLink>? = null,
+ customButtons: List<FormItem> = emptyList()
+) :
+ Displayable, RoWindow(caption = caption, closeButton = true, menu = menu) {
private val okButton = Button(
- text = defaultAction,
- icon = IconManager.find(defaultAction),
- style = ButtonStyle.SUCCESS)
- .onClick {
- execute()
- }
+ text = defaultAction,
+ icon = IconManager.find(defaultAction),
+ style = ButtonStyle.SUCCESS
+ )
+ .onClick {
+ execute()
+ }
private val cancelButton = Button(
- "Cancel",
- "fas fa-times",
- ButtonStyle.OUTLINEINFO)
- .onClick {
- close()
- }
+ "Cancel",
+ "fas fa-times",
+ ButtonStyle.OUTLINEINFO
+ )
+ .onClick {
+ close()
+ }
@Deprecated("remove once leaflet/svg is fully operational")
private val scaleUpButton = Button(
- "",
- "fas fa-plus",
- ButtonStyle.OUTLINEINFO)
- .onClick {
- (command as DiagramDialog).scale(Direction.UP)
- }
+ "",
+ "fas fa-plus",
+ ButtonStyle.OUTLINEINFO
+ )
+ .onClick {
+ (command as DiagramDialog).scale(Direction.UP)
+ }
@Deprecated("remove once leaflet/svg is fully operational")
private val scaleDownButton = Button(
- "",
- "fas fa-minus",
- ButtonStyle.OUTLINEINFO)
- .onClick {
- (command as DiagramDialog).scale(Direction.DOWN)
- }
+ "",
+ "fas fa-minus",
+ ButtonStyle.OUTLINEINFO
+ )
+ .onClick {
+ (command as DiagramDialog).scale(Direction.DOWN)
+ }
var formPanel: FormPanel<String>? = null
@@ -98,9 +103,8 @@ class RoDialog(
add(formPanel!!, grow = 2)
- val buttonBar = HPanel(
- spacing = 10,
- classes = setOf("button-bar"))
+ val buttonBar = HPanel(spacing = 10)
+ buttonBar.addCssClass("button-bar")
buttonBar.add(okButton)
customButtons.forEach {
val b = createButton(it)
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoMenuBar.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoMenuBar.kt
index ec07964..2427639 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoMenuBar.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoMenuBar.kt
@@ -59,80 +59,90 @@ object RoMenuBar : SimplePanel() {
private fun buildMainMenu(): DropDown {
return dropDown(
- "",
- icon = IconManager.find("Burger"),
- forNavbar = false,
- style = ButtonStyle.LIGHT)
+ "",
+ icon = IconManager.find("Burger"),
+ forNavbar = false,
+ style = ButtonStyle.LIGHT
+ )
{
ddLink(
- "Connect ...",
- icon = IconManager.find("Connect")
+ "Connect ...",
+ icon = IconManager.find("Connect")
).onClick { e ->
val at = Point(e.pageX.toInt(), e.pageY.toInt())
LoginPrompt().open(at)
}
val toolTitle = "Toolbar"
- ddLink(toolTitle,
- icon = IconManager.find(toolTitle)
+ ddLink(
+ toolTitle,
+ icon = IconManager.find(toolTitle)
).onClick {
RoIconBar.toggle()
}
val sampleTitle = "History"
- ddLink(sampleTitle,
- icon = IconManager.find(sampleTitle)
+ ddLink(
+ sampleTitle,
+ icon = IconManager.find(sampleTitle)
).onClick {
val model = EventStore.log
UiManager.add("Log Entries", EventLogTable(model))
}
val chartTitle = "Sample Chart"
- ddLink(chartTitle,
- icon = IconManager.find("Chart")
+ ddLink(
+ chartTitle,
+ icon = IconManager.find("Chart")
).onClick {
UiManager.add(chartTitle, EventChart(SampleChartModel()))
}
val geoMapTitle = "Sample Geo Map"
- ddLink(geoMapTitle,
- icon = IconManager.find("Map")
+ ddLink(
+ geoMapTitle,
+ icon = IconManager.find("Map")
).onClick {
UiManager.add(geoMapTitle, GeoMap())
}
val svgMapTitle = "Sample SVG Map"
- ddLink(svgMapTitle,
- icon = IconManager.find("Diagram")
+ ddLink(
+ svgMapTitle,
+ icon = IconManager.find("Diagram")
).onClick {
UiManager.add(svgMapTitle, SvgMap())
}
val svgInlineTitle = "Sample SVG Inline (interactive)"
- ddLink(svgInlineTitle,
- icon = IconManager.find("Diagram")
+ ddLink(
+ svgInlineTitle,
+ icon = IconManager.find("Diagram")
).onClick {
SvgInline().open()
}
val imageTitle = "Sample Image"
- ddLink(imageTitle,
- icon = IconManager.find("Image")
+ ddLink(
+ imageTitle,
+ icon = IconManager.find("Image")
).onClick {
val panel = ImageSample()
RoView.addTab(imageTitle, panel)
}
val searchTitle = "Dropdown search example"
- ddLink(searchTitle,
- icon = IconManager.find("Find")
+ ddLink(
+ searchTitle,
+ icon = IconManager.find("Find")
).onClick {
UiManager.add(searchTitle, DropdownSearch())
}
val aboutTitle = "About"
- ddLink(aboutTitle,
- icon = IconManager.find(aboutTitle)
+ ddLink(
+ aboutTitle,
+ icon = IconManager.find(aboutTitle)
).onClick {
About().open()
}
@@ -151,10 +161,11 @@ object RoMenuBar : SimplePanel() {
private fun logoButton() {
val classes = setOf("isis-logo-button-image", "logo-button")
- val logo = Button("", style = ButtonStyle.LINK, classes = classes)
- .onClick {
- window.open("https://isis.apache.org")
- }
+ val logo = Button("", style = ButtonStyle.LINK)
+ logo.addCssClass(classes.toString())
+ logo.onClick {
+ window.open("https://isis.apache.org")
+ }
nav.add(logo)
}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoStatusBar.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoStatusBar.kt
index ee5bd00..5f68f86 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoStatusBar.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoStatusBar.kt
@@ -35,9 +35,9 @@ import org.apache.isis.client.kroviz.ui.dialog.NotificationDialog
import org.apache.isis.client.kroviz.utils.IconManager
object RoStatusBar {
- val navbar = Navbar(
- type = NavbarType.FIXEDBOTTOM,
- classes = setOf("status-bar"))
+ val navbar = Navbar(type = NavbarType.FIXEDBOTTOM)
+
+ //FIXME navbar.addCssClasses("status-bar")
private val nav = Nav(rightAlign = true)
private val userBtn: Button = buildButton("", "Me", ButtonStyle.OUTLINEWARNING)
private val classDiagram = buildButton("", "Diagram", ButtonStyle.OUTLINEWARNING)
@@ -46,9 +46,10 @@ object RoStatusBar {
private fun buildButton(text: String, iconName: String, style: ButtonStyle): Button {
return Button(
- text = text,
- icon = IconManager.find(iconName),
- style = style).apply {
+ text = text,
+ icon = IconManager.find(iconName),
+ style = style
+ ).apply {
padding = CssSize(-16, UNIT.px)
margin = CssSize(0, UNIT.px)
}
@@ -117,18 +118,20 @@ object RoStatusBar {
private fun isisButton(): Button {
val classes = setOf("isis-logo-button-image", "logo-button")
- return Button("", style = ButtonStyle.LINK, classes = classes)
- .onClick {
- window.open("https://isis.apache.org")
- }
+ val b = Button("", style = ButtonStyle.LINK)
+ b.addCssClass(classes.toString())
+ return b.onClick {
+ window.open("https://isis.apache.org")
+ }
}
private fun kvisionButton(): Button {
val classes = setOf("kvision-logo-button-image", "logo-button")
- return Button("", style = ButtonStyle.LINK, classes = classes)
- .onClick {
- window.open("https://kvision.io")
- }
+ val b = Button("", style = ButtonStyle.LINK)
+ b.addCssClass(classes.toString())
+ return b.onClick {
+ window.open("https://kvision.io")
+ }
}
}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoTable.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoTable.kt
index 1dbe848..531e64d 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoTable.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/RoTable.kt
@@ -22,7 +22,7 @@ import io.kvision.core.Container
import io.kvision.core.CssSize
import io.kvision.core.UNIT
import io.kvision.panel.SimplePanel
-import io.kvision.table.TableType
+import io.kvision.tabulator.TableType
import io.kvision.tabulator.Layout
import io.kvision.tabulator.Tabulator
import io.kvision.tabulator.TabulatorOptions
@@ -59,7 +59,7 @@ class RoTable(displayCollection: CollectionDM) : SimplePanel() {
tabulator(model, options = options, types = tableTypes) {
setEventListener<Tabulator<Exposer>> {
- tabulatorCellClick = {
+ cellClickTabulator = {
// can't check cast to external interface
val cc = it.detail as CellComponent
val column = cc.getColumn().getField()
@@ -96,7 +96,8 @@ class RoTable(displayCollection: CollectionDM) : SimplePanel() {
classes: Set<String> = setOf(),
init: (Tabulator<T>.() -> Unit)? = null
): Tabulator<T> {
- val tabulator = Tabulator(data, dataUpdateOnEdit, options, types, classes)
+ val tabulator = Tabulator(data, dataUpdateOnEdit, options, types)
+ tabulator.addCssClass(classes.toString())
init?.invoke(tabulator)
return tabulator
}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/override/RoTab.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/override/RoTab.kt
index 4b017d2..a9dbc58 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/override/RoTab.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/override/RoTab.kt
@@ -32,9 +32,8 @@ import io.kvision.html.Icon
import io.kvision.html.Link
import io.kvision.html.TAG
import io.kvision.html.Tag
+import io.kvision.panel.TabPanel
import io.kvision.routing.RoutingManager
-import io.kvision.state.ObservableState
-import io.kvision.state.bind
import io.kvision.utils.obj
import org.apache.isis.client.kroviz.utils.DomUtil
import org.apache.isis.client.kroviz.utils.ScalableVectorGraphic
@@ -51,22 +50,19 @@ import org.apache.isis.client.kroviz.utils.ScalableVectorGraphic
* @param init an initializer extension function
*/
open class RoTab(
+ label: String? = null, icon: String? = null,
+ image: ResString? = null, closable: Boolean = false, val route: String? = null,
+ init: (RoTab.() -> Unit)? = null
+) : Tag(TAG.LI, className = "nav-item") {
+
+ constructor(
label: String? = null,
+ child: Component,
icon: String? = null,
image: ResString? = null,
closable: Boolean = false,
- val route: String? = null,
+ route: String? = null,
init: (RoTab.() -> Unit)? = null
-) : Tag(TAG.LI, classes = setOf("nav-item")) {
-
- constructor(
- label: String? = null,
- child: Component,
- icon: String? = null,
- image: ResString? = null,
- closable: Boolean = false,
- route: String? = null,
- init: (RoTab.() -> Unit)? = null
) : this(label, icon, image, closable, route, init) {
@Suppress("LeakingThis")
add(child)
@@ -115,20 +111,20 @@ open class RoTab(
closeIcon.visible = value
}
- internal val closeIcon = Icon("fas fa-times").apply {
+ protected val closeIcon = Icon("fas fa-times").apply {
addCssClass("kv-tab-close")
visible = closable
setEventListener<Icon> {
click = { e ->
- val tabPanel = (this@RoTab.parent as? RoTabPanelNav)?.tabPanel
+ val tabPanel = (this@RoTab.parent as? RoTabPanel.TabPanelNav)?.tabPanel
val actIndex = tabPanel?.getTabIndex(this@RoTab) ?: -1
e.asDynamic().data = actIndex
@Suppress("UnsafeCastFromDynamic")
- val event = org.w3c.dom.CustomEvent("tabClosing", obj { detail = e; cancelable = true })
+ val event = org.w3c.dom.CustomEvent("closingTab", obj { detail = e; cancelable = true })
if (tabPanel?.getElement()?.dispatchEvent(event) != false) {
tabPanel?.removeTab(actIndex)
@Suppress("UnsafeCastFromDynamic")
- val closed = org.w3c.dom.CustomEvent("tabClosed", obj { detail = e })
+ val closed = org.w3c.dom.CustomEvent("closedTab", obj { detail = e })
tabPanel?.getElement()?.dispatchEvent(closed)
}
e.stopPropagation()
@@ -139,20 +135,20 @@ open class RoTab(
/**
* A link component within the tab.
*/
- val link = Link(label ?: "", "#", icon, image, classes = setOf("nav-link")).apply {
+ val link = Link(label ?: "", "#", icon, image, className = "nav-link").apply {
add(this@RoTab.closeIcon)
}
internal val tabId = counter++
protected val routingHandler = { _: Any ->
- (this@RoTab.parent as? RoTabPanelNav)?.tabPanel?.activeTab = this
+ (this@RoTab.parent as? RoTabPanel.TabPanelNav)?.tabPanel?.activeTab = this
}
init {
addPrivate(link)
onClick { e ->
- (this@RoTab.parent as? RoTabPanelNav)?.tabPanel?.activeTab = this
+ (this@RoTab.parent as? RoTabPanel.TabPanelNav)?.tabPanel?.activeTab = this
e.preventDefault()
if (route != null) {
RoutingManager.getRouter().kvNavigate(route)
@@ -168,7 +164,7 @@ open class RoTab(
}
override fun childrenVNodes(): Array<VNode> {
- return (privateChildren).filter { it.visible }.map { it.renderVNode() }.toTypedArray()
+ return (privateChildren!!).filter { it.visible }.map { it.renderVNode() }.toTypedArray()
}
override fun dispose() {
@@ -186,25 +182,12 @@ open class RoTab(
*
* It takes the same parameters as the constructor of the built component.
*/
-fun RoTabPanel.tab(
- label: String? = null, icon: String? = null,
- image: ResString? = null, closable: Boolean = false, route: String? = null,
- init: (RoTab.() -> Unit)? = null
+fun TabPanel.tab(
+ label: String? = null, icon: String? = null,
+ image: ResString? = null, closable: Boolean = false, route: String? = null,
+ init: (RoTab.() -> Unit)? = null
): RoTab {
val tab = RoTab(label, icon, image, closable, route, init)
this.add(tab)
return tab
}
-
-/**
- * DSL builder extension function for observable state.
- *
- * It takes the same parameters as the constructor of the built component.
- */
-fun <S> RoTabPanel.tab(
- state: ObservableState<S>,
- label: String? = null, icon: String? = null,
- image: ResString? = null, closable: Boolean = false, route: String? = null,
- init: (RoTab.(S) -> Unit)
-) = tab(label, icon, image, closable, route).bind(state, true, init)
-
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/override/RoTabPanel.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/override/RoTabPanel.kt
index 9ca5846..bb1390f 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/override/RoTabPanel.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/override/RoTabPanel.kt
@@ -26,13 +26,11 @@ package org.apache.isis.client.kroviz.ui.kv.override
import com.github.snabbdom.VNode
import io.kvision.core.*
import io.kvision.panel.SimplePanel
+import io.kvision.panel.Tab
import io.kvision.panel.VPanel
import io.kvision.routing.RoutingManager
-import io.kvision.state.ObservableState
-import io.kvision.state.bind
import io.kvision.utils.auto
import io.kvision.utils.obj
-import io.kvision.utils.set
import org.apache.isis.client.kroviz.ui.core.RoView
/**
@@ -66,29 +64,29 @@ enum class SideTabSize {
* @param sideTabSize side tab size
* @param scrollableTabs determines if tabs are scrollable (default: false)
* @param draggableTabs determines if tabs are draggable (default: false)
- * @param classes a set of CSS class names
+ * @param className CSS class names
* @param init an initializer extension function
*/
@Suppress("LeakingThis")
open class RoTabPanel(
- private val tabPosition: TabPosition = TabPosition.TOP,
- private val sideTabSize: SideTabSize = SideTabSize.SIZE_3,
- val scrollableTabs: Boolean = false,
- val draggableTabs: Boolean = false,
- classes: Set<String> = setOf(),
- init: (RoTabPanel.() -> Unit)? = null
-) : SimplePanel(classes) {
-
- private val navClasses = when (tabPosition) {
- TabPosition.TOP -> if (scrollableTabs) setOf("nav", "nav-tabs", "tabs-top") else setOf("nav", "nav-tabs")
- TabPosition.LEFT -> setOf("nav", "nav-tabs", "tabs-left", "flex-column")
- TabPosition.RIGHT -> setOf("nav", "nav-tabs", "tabs-right", "flex-column")
+ protected val tabPosition: TabPosition = TabPosition.TOP,
+ protected val sideTabSize: SideTabSize = SideTabSize.SIZE_3,
+ val scrollableTabs: Boolean = false,
+ val draggableTabs: Boolean = false,
+ className: String? = null,
+ init: (RoTabPanel.() -> Unit)? = null
+) : SimplePanel((className?.let { "$it " } ?: "") + "kv-tab-panel") {
+
+ protected val navClasses = when (tabPosition) {
+ TabPosition.TOP -> if (scrollableTabs) "nav nav-tabs tabs-top" else "nav nav-tabs"
+ TabPosition.LEFT -> "nav nav-tabs tabs-left flex-column"
+ TabPosition.RIGHT -> "nav nav-tabs tabs-right flex-column"
}
internal val tabs = mutableListOf<RoTab>()
- private val nav = RoTabPanelNav(this, navClasses)
- private val content = RoTabPanelContent(this)
+ private val nav = TabPanelNav(this, navClasses)
+ private val content = TabPanelContent(this)
/**
* The index of the active tab.
@@ -102,7 +100,7 @@ open class RoTabPanel(
}
tabs.getOrNull(value)?.link?.addCssClass("active")
@Suppress("UnsafeCastFromDynamic")
- this.dispatchEvent("tabChange", obj { detail = obj { data = value } })
+ this.dispatchEvent("changeTab", obj { detail = obj { data = value } })
}
}
@@ -116,6 +114,7 @@ open class RoTabPanel(
}
init {
+ //TODO to be set by caller
width = auto
marginTop = CssSize(40, UNIT.px)
when (tabPosition) {
@@ -127,25 +126,21 @@ open class RoTabPanel(
this.addSurroundingCssClass("container-fluid")
this.addCssClass("row")
val sizes = calculateSideClasses()
- this.addPrivate(WidgetWrapper(nav, setOf(sizes.first, "pl-0", "pr-0")))
- this.addPrivate(WidgetWrapper(content, setOf(sizes.second, "pl-0", "pr-0")))
+ this.addPrivate(WidgetWrapper(nav, "${sizes.first} ps-0 pe-0"))
+ this.addPrivate(WidgetWrapper(content, "${sizes.second} ps-0 pe-0"))
}
TabPosition.RIGHT -> {
this.addSurroundingCssClass("container-fluid")
this.addCssClass("row")
val sizes = calculateSideClasses()
- this.addPrivate(WidgetWrapper(content, setOf(sizes.second, "pl-0", "pr-0")))
- this.addPrivate(WidgetWrapper(nav, setOf(sizes.first, "pl-0", "pr-0")))
+ this.addPrivate(WidgetWrapper(content, "${sizes.second} ps-0 pe-0"))
+ this.addPrivate(WidgetWrapper(nav, "${sizes.first} ps-0 pe-0"))
}
}
init?.invoke(this)
}
- override fun render(): VNode {
- return render("div", childrenVNodes())
- }
-
- private fun calculateSideClasses(): Pair<String, String> {
+ protected fun calculateSideClasses(): Pair<String, String> {
return when (sideTabSize) {
SideTabSize.SIZE_1 -> Pair("col-sm-1", "col-sm-11")
SideTabSize.SIZE_2 -> Pair("col-sm-2", "col-sm-10")
@@ -379,6 +374,33 @@ open class RoTabPanel(
return null
}
+ /**
+ * A helper component for rendering tabs.
+ */
+ class TabPanelNav(internal val tabPanel: RoTabPanel, className: String) : SimplePanel(className) {
+
+ override fun render(): VNode {
+ return render("ul", childrenVNodes())
+ }
+
+ override fun childrenVNodes(): Array<VNode> {
+ return tabPanel.tabs.filter { it.visible }.map { it.renderVNode() }.toTypedArray()
+ }
+
+ }
+
+ /**
+ * A helper component for rendering tab content.
+ */
+ class TabPanelContent(private val tabPanel: RoTabPanel) : SimplePanel() {
+
+ override fun childrenVNodes(): Array<VNode> {
+ return tabPanel.tabs.getOrNull(tabPanel.activeIndex)?.getChildren()?.map { it.renderVNode() }
+ ?.toTypedArray()
+ ?: emptyArray()
+ }
+
+ }
}
/**
@@ -387,54 +409,14 @@ open class RoTabPanel(
* It takes the same parameters as the constructor of the built component.
*/
fun Container.tabPanel(
- tabPosition: TabPosition = TabPosition.TOP,
- sideTabSize: SideTabSize = SideTabSize.SIZE_3,
- scrollableTabs: Boolean = false,
- draggableTabs: Boolean = false,
- classes: Set<String>? = null,
- className: String? = null,
- init: (RoTabPanel.() -> Unit)? = null
+ tabPosition: TabPosition = TabPosition.TOP,
+ sideTabSize: SideTabSize = SideTabSize.SIZE_3,
+ scrollableTabs: Boolean = false,
+ draggableTabs: Boolean = false,
+ className: String? = null,
+ init: (RoTabPanel.() -> Unit)? = null
): RoTabPanel {
- val tabPanel = RoTabPanel(tabPosition, sideTabSize, scrollableTabs, draggableTabs, classes ?: className.set, init)
+ val tabPanel = RoTabPanel(tabPosition, sideTabSize, scrollableTabs, draggableTabs, className, init)
this.add(tabPanel)
return tabPanel
}
-
-/**
- * DSL builder extension function for observable state.
- *
- * It takes the same parameters as the constructor of the built component.
- */
-fun <S> Container.tabPanel(
- state: ObservableState<S>,
- tabPosition: TabPosition = TabPosition.TOP,
- sideTabSize: SideTabSize = SideTabSize.SIZE_3,
- scrollableTabs: Boolean = false,
- draggableTabs: Boolean = false,
- classes: Set<String>? = null,
- className: String? = null,
- init: (RoTabPanel.(S) -> Unit)
-) = tabPanel(tabPosition, sideTabSize, scrollableTabs, draggableTabs, classes, className).bind(state, true, init)
-
-
-internal class RoTabPanelNav(internal val tabPanel: RoTabPanel, classes: Set<String>) : SimplePanel(classes) {
-
- override fun render(): VNode {
- return render("ul", childrenVNodes())
- }
-
- override fun childrenVNodes(): Array<VNode> {
- return tabPanel.tabs.filter { it.visible }.map { it.renderVNode() }.toTypedArray()
- }
-
-}
-
-internal class RoTabPanelContent(private val tabPanel: RoTabPanel) : SimplePanel() {
-
- override fun childrenVNodes(): Array<VNode> {
- return tabPanel.tabs.getOrNull(tabPanel.activeIndex)?.getChildren()?.map { it.renderVNode() }?.toTypedArray()
- ?: emptyArray()
- }
-
-}
-
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/override/RoWindow.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/override/RoWindow.kt
index 5f5d1f1..146cbbf 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/override/RoWindow.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/override/RoWindow.kt
@@ -71,7 +71,7 @@ open class RoWindow(
menu: List<KvisionHtmlLink>? = null,
init: (RoWindow.() -> Unit)? = null
) :
- SimplePanel(classes + setOf("modal-content", "kv-window")) {
+ SimplePanel(classes.toString() +" modal-content kv-window") {
/**
* Window caption text.
@@ -160,7 +160,7 @@ open class RoWindow(
windowIcon.visible = (value != null && value != "")
}
- private val header = SimplePanel(setOf("modal-header"))
+ private val header = SimplePanel("modal-header")
/**
* @suppress
@@ -173,10 +173,11 @@ open class RoWindow(
private val closeIcon = CloseIcon()
private val maximizeIcon = MaximizeIcon()
private val minimizeIcon = MinimizeIcon()
- private val captionTag = Tag(TAG.H5, caption, classes = setOf("modal-title")).apply {
+ private val captionTag = Tag(TAG.H5, caption).apply {
+ addCssClass("modal-title")
alignSelf = AlignItems.START
}
- private val iconsContainer = SimplePanel(setOf("kv-window-icons-container"))
+ private val iconsContainer = SimplePanel("kv-window-icons-container")
private val windowIcon = Icon(icon ?: "").apply {
addCssClass("window-icon")
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventLogTable.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventLogTable.kt
index 12885e8..db3505b 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventLogTable.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventLogTable.kt
@@ -154,8 +154,6 @@ class EventLogTable(val model: List<LogEntry>) : VPanel() {
tabulator = tabulator(model, options = options) {
setEventListener<Tabulator<LogEntry>> {
- tabulatorRowClick = {
- }
}
}
}