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/11/22 19:34:55 UTC

[isis] branch master updated (18c690f -> 2f7a53e)

This is an automated email from the ASF dual-hosted git repository.

joergrade pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git.


    from 18c690f  ISIS-2877: adds a bunch more value-type test scenarios
     new 3f0aff0  ISIS-2348 HttpError interface name changed
     new a2821bc  ISIS-2348 Add open to Command interface, amend LoginPrompt with nextCommand
     new 56a5e16  ISIS-2348 Pull up refactoring/Command; EventCompareDialog added
     new 13b4c73  ISIS-2348 EventCompareDialog opens
     new b1bf260  ISIS-2348 EventComparison works
     new 2f7a53e  Merge branch 'master' of https://github.com/apache/isis

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../kroviz/core/aggregator/ErrorDispatcher.kt      |   5 +-
 .../isis/client/kroviz/core/event/EventStore.kt    |   5 +
 .../isis/client/kroviz/core/event/LogEntry.kt      |   1 -
 .../client/kroviz/core/event/LogEntryComparison.kt |  82 +++++++++++++++
 .../isis/client/kroviz/core/event/ReplayCommand.kt |  26 +++--
 .../isis/client/kroviz/to/PlainTransferObjects.kt  |   6 +-
 .../isis/client/kroviz/ui/core/ColumnFactory.kt    |   1 -
 .../apache/isis/client/kroviz/ui/core/RoMenuBar.kt |  25 +----
 .../client/kroviz/ui/diagram/LinkTreeDiagram.kt    |   4 +-
 .../apache/isis/client/kroviz/ui/dialog/About.kt   |   7 --
 .../isis/client/kroviz/ui/dialog/ActionPrompt.kt   |  10 +-
 .../isis/client/kroviz/ui/dialog/BrowserWindow.kt  |   2 +-
 .../apache/isis/client/kroviz/ui/dialog/Command.kt |   6 ++
 .../isis/client/kroviz/ui/dialog/DiagramDialog.kt  |   7 +-
 .../isis/client/kroviz/ui/dialog/DownloadDialog.kt |   7 +-
 .../isis/client/kroviz/ui/dialog/ErrorDialog.kt    |   8 +-
 .../{DownloadDialog.kt => EventCompareDialog.kt}   |  38 ++++---
 .../isis/client/kroviz/ui/dialog/EventDialog.kt    |   9 +-
 .../client/kroviz/ui/dialog/EventExportDialog.kt   |  20 ++--
 .../client/kroviz/ui/dialog/EventImportDialog.kt   |  20 ++--
 .../isis/client/kroviz/ui/dialog/EventLogDetail.kt |   9 +-
 .../{ReplayDiffDialog.kt => EventReplayDialog.kt}  |  42 +++++---
 .../isis/client/kroviz/ui/dialog/FileDialog.kt     |   2 +-
 .../isis/client/kroviz/ui/dialog/LoginPrompt.kt    |  26 +++--
 .../client/kroviz/ui/dialog/NotificationDialog.kt  |   3 +-
 ...ayDiffDialog.kt => ResponseComparisonDialog.kt} |  51 +++------
 .../isis/client/kroviz/ui/dialog/SvgInline.kt      |   6 --
 .../client/kroviz/ui/dialog/UndefinedDialog.kt     |   4 +-
 .../client/kroviz/ui/panel/EventComparisonTable.kt | 117 +++++++++++++++++++++
 .../apache/isis/client/kroviz/utils/StringUtils.kt |   5 +-
 .../isis/client/kroviz/util/StringUtilsTest.kt     |   2 +-
 31 files changed, 358 insertions(+), 198 deletions(-)
 create mode 100644 incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryComparison.kt
 copy incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/{DownloadDialog.kt => EventCompareDialog.kt} (50%)
 copy incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/{ReplayDiffDialog.kt => EventReplayDialog.kt} (65%)
 rename incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/{ReplayDiffDialog.kt => ResponseComparisonDialog.kt} (52%)
 create mode 100644 incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventComparisonTable.kt

[isis] 04/06: ISIS-2348 EventCompareDialog opens

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

joergrade pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 13b4c73315a10e86e2ee3d164c3114430136e971
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Sun Nov 21 21:27:02 2021 +0100

    ISIS-2348 EventCompareDialog opens
---
 .../client/kroviz/core/event/LogEntryComparison.kt |  25 +++--
 .../client/kroviz/ui/dialog/EventCompareDialog.kt  |   5 +-
 .../client/kroviz/ui/dialog/ReplayDiffDialog.kt    |   2 +-
 .../client/kroviz/ui/panel/EventComparisonTable.kt | 124 +++++++++++++++++++++
 4 files changed, 144 insertions(+), 12 deletions(-)

diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryComparison.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryComparison.kt
index 5274845..37119b9 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryComparison.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryComparison.kt
@@ -19,6 +19,7 @@
 package org.apache.isis.client.kroviz.core.event
 
 import io.kvision.html.ButtonStyle
+import kotlinx.serialization.Serializable
 
 enum class ChangeType(val id: String, val iconName: String, val style: ButtonStyle) {
     ADDED("ADDED", "fas fa-plus", ButtonStyle.INFO),
@@ -28,20 +29,28 @@ enum class ChangeType(val id: String, val iconName: String, val style: ButtonSty
     ERROR("ERROR", "fas fa-bug", ButtonStyle.OUTLINEDANGER),
 }
 
-class LogEntryComparison(val expected: LogEntry?, val actual: LogEntry?) {
+@Serializable
+data class LogEntryComparison(val expected: LogEntry?, val actual: LogEntry?) {
     var changeType: ChangeType
+    var title: String
     var iconName: String
-    var expectedResponse: String?
-    var actualResponse: String?
+    var expectedResponse: String? = null
+    var actualResponse: String? = null
 
     init {
         if (expected == null && actual == null) {
-            throw Throwable("[LogEntryComparison.init] actual and expected not set")
+            throw Throwable("[LogEntryComparison.init] neither actual nor expected set")
         } else {
             changeType = compare()
             iconName = changeType.iconName
-            expectedResponse = expected?.response
-            actualResponse = actual?.response
+            if (expected == null) {
+                actualResponse = actual?.response
+                title = actual?.title.toString()
+            } else {
+                expectedResponse = expected.response
+                title = expected.title
+            }
+
         }
     }
 
@@ -57,8 +66,8 @@ class LogEntryComparison(val expected: LogEntry?, val actual: LogEntry?) {
     }
 
     private fun areResponsesEqual(): Boolean {
-        val expectedBaseUrl: String = ""
-        val actualBaseUrl: String = "" //FIXME
+        val expectedBaseUrl = ""
+        val actualBaseUrl = "" //FIXME
         val expected = expectedResponse?.replace(expectedBaseUrl, "")
         val actual = actualResponse?.replace(actualBaseUrl, "")
         return (expected == actual)
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt
index d5804f5..2f4c960 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt
@@ -24,8 +24,7 @@ import io.kvision.core.UNIT
 import io.kvision.panel.VPanel
 import org.apache.isis.client.kroviz.core.event.LogEntryComparison
 import org.apache.isis.client.kroviz.ui.core.RoDialog
-import org.apache.isis.client.kroviz.ui.core.UiManager
-import org.apache.isis.client.kroviz.ui.panel.EventLogTable
+import org.apache.isis.client.kroviz.ui.panel.EventComparisonTable
 
 class EventCompareDialog(val data: List<LogEntryComparison>) : Command() {
 
@@ -43,7 +42,7 @@ class EventCompareDialog(val data: List<LogEntryComparison>) : Command() {
             heightPerc = 70,
         )
         //FIXME -> reuse -> ColumnFactory and RoTable if possible
-        val table = EventLogTable(UiManager.getEventStore().log)
+        val table = EventComparisonTable(data)
         table.tabulator.addCssClass("tabulator-in-dialog")
         panel.add(table)
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ReplayDiffDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ReplayDiffDialog.kt
index c5d0a68..7f4a20e 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ReplayDiffDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ReplayDiffDialog.kt
@@ -86,7 +86,7 @@ class ReplayDiffDialog(
         // second pass: iterate over actual
         val actualEvents = actualStore.log
         val expectedStore = EventStore()
-        expectedStore.log = expectedEvents as ObservableList<LogEntry>
+        expectedStore.log.addAll(expectedEvents)
         actualEvents.forEach {
             val rs = ResourceSpecification(it.url, it.subType)
             val expectedEvent = expectedStore.findBy(rs)
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventComparisonTable.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventComparisonTable.kt
new file mode 100644
index 0000000..d58c8c1
--- /dev/null
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventComparisonTable.kt
@@ -0,0 +1,124 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.client.kroviz.ui.panel
+
+import io.kvision.core.*
+import io.kvision.html.Button
+import io.kvision.html.ButtonStyle
+import io.kvision.panel.VPanel
+import io.kvision.panel.hPanel
+import io.kvision.tabulator.*
+import io.kvision.utils.px
+import org.apache.isis.client.kroviz.core.event.LogEntry
+import org.apache.isis.client.kroviz.core.event.LogEntryComparison
+import org.apache.isis.client.kroviz.to.TObject
+import org.apache.isis.client.kroviz.ui.core.Constants
+import org.apache.isis.client.kroviz.ui.dialog.EventLogDetail
+import org.apache.isis.client.kroviz.utils.StringUtils
+
+class EventComparisonTable(val model: List<LogEntryComparison>) : VPanel() {
+    val tabulator: Tabulator<LogEntryComparison>
+
+    private val columns = listOf(
+        ColumnDefinition<LogEntryComparison>(
+            download = false,
+            title = "",
+            field = "changeType",
+            width = "50",
+   //         headerMenu = DynamicMenuBuilder().buildTableMenu(this),
+            hozAlign = Align.CENTER,
+            vertAlign = VAlign.MIDDLE,
+            formatterComponentFunction = { _, _, data -> buildActionButton(data) }
+        ),
+        ColumnDefinition(
+            download = false,
+            title = "Title",
+            field = "title",
+            headerFilter = Editor.INPUT,
+            width = "200",
+            formatterComponentFunction = { _, _, data -> buildObjectButton(data) }
+        ),
+        ColumnDefinition(
+            download = false,
+            title = "expectedResponse",
+            field = "expectedResponse",
+            headerFilter = Editor.INPUT,
+            width = "400",
+        ),
+        ColumnDefinition(
+            download = false,
+            title = "actualResponse",
+            field = "actualResponse",
+            headerFilter = Editor.INPUT,
+            width = "400",
+        )
+    )
+
+    private fun buildObjectButton(data: LogEntryComparison): Button {
+        val b = Button(
+            text = StringUtils.shorten(data.title),
+            icon = data.changeType.iconName,
+            style = ButtonStyle.LINK
+        )
+        b.onClick {
+            kotlinx.browser.window.open(data.title) //IMPROVE should be URL
+        }
+        //val tto = TooltipOptions(title = data.title)
+        // tabulator tooltip is buggy: often the tooltip doesn't go away and the color is not settable
+        //b.enableTooltip(tto)
+    //    if (data.obj is TObject) b.setDragDropData(Constants.stdMimeType, data.url)
+        return b
+    }
+
+    private fun buildActionButton(data: LogEntryComparison): Button {
+        val b = Button(
+            text = "",
+            icon = "fa fa-info-circle",
+            style = data.changeType.style
+        )
+//        b.onClick { EventLogDetail(data).open() }
+        b.margin = CssSize(-10, UNIT.px)
+        b.addCssClass("btn-sm")
+        return b
+    }
+
+    init {
+        hPanel(
+            FlexWrap.NOWRAP,
+            alignItems = AlignItems.CENTER,
+            spacing = 20
+        ) {
+            border = Border(width = 1.px)
+        }
+
+        val options = TabulatorOptions(
+            movableColumns = true,
+            height = Constants.calcHeight,
+            layout = Layout.FITCOLUMNS,
+            columns = columns,
+            persistenceMode = false
+        )
+
+        tabulator = tabulator(model, options = options) {
+            setEventListener<Tabulator<LogEntryComparison>> {
+            }
+        }
+    }
+
+}

[isis] 03/06: ISIS-2348 Pull up refactoring/Command; EventCompareDialog added

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

joergrade pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 56a5e167ad4545625003cb0e58267f1e4800a057
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Sun Nov 21 14:06:02 2021 +0100

    ISIS-2348 Pull up refactoring/Command; EventCompareDialog added
---
 .../isis/client/kroviz/core/event/LogEntry.kt      |  1 -
 .../client/kroviz/core/event/LogEntryComparison.kt | 67 ++++++++++++++++++++++
 .../isis/client/kroviz/core/event/ReplayCommand.kt |  2 +-
 .../isis/client/kroviz/ui/core/ColumnFactory.kt    |  1 -
 .../apache/isis/client/kroviz/ui/dialog/About.kt   |  6 --
 .../isis/client/kroviz/ui/dialog/ActionPrompt.kt   | 10 ++--
 .../apache/isis/client/kroviz/ui/dialog/Command.kt |  4 +-
 .../isis/client/kroviz/ui/dialog/DiagramDialog.kt  |  3 +-
 .../isis/client/kroviz/ui/dialog/DownloadDialog.kt |  5 +-
 .../client/kroviz/ui/dialog/EventCompareDialog.kt  | 56 ++++++++++++++++++
 .../isis/client/kroviz/ui/dialog/EventDialog.kt    |  9 +--
 .../client/kroviz/ui/dialog/EventExportDialog.kt   | 18 +++---
 .../client/kroviz/ui/dialog/EventImportDialog.kt   | 18 +++---
 .../isis/client/kroviz/ui/dialog/EventLogDetail.kt |  7 +--
 .../isis/client/kroviz/ui/dialog/LoginPrompt.kt    | 10 ++--
 .../client/kroviz/ui/dialog/NotificationDialog.kt  |  1 -
 .../client/kroviz/ui/dialog/ReplayDiffDialog.kt    | 36 +++++++-----
 .../isis/client/kroviz/ui/dialog/SvgInline.kt      |  6 --
 .../client/kroviz/ui/dialog/UndefinedDialog.kt     |  2 +-
 19 files changed, 182 insertions(+), 80 deletions(-)

diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntry.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntry.kt
index 6e6ebc1..e83d0e9 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntry.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntry.kt
@@ -47,7 +47,6 @@ enum class EventState(val id: String, val iconName: String, val style: ButtonSty
     CLOSED("CLOSED", "fas fa-eye-slash", ButtonStyle.OUTLINEINFO),
     RELOAD("RELOAD", "fas fa-retweet", ButtonStyle.OUTLINEWARNING),
     MISSING("MISSING", "fas fa-bug", ButtonStyle.OUTLINEDANGER),
-    DIFF("DIFF", "fas fa-bell", ButtonStyle.DANGER),
     // IMPROVE multiple aspects intermangled: req/resp, view, as well as cache
     // encapsulate access with managers?
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryComparison.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryComparison.kt
new file mode 100644
index 0000000..5274845
--- /dev/null
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryComparison.kt
@@ -0,0 +1,67 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.client.kroviz.core.event
+
+import io.kvision.html.ButtonStyle
+
+enum class ChangeType(val id: String, val iconName: String, val style: ButtonStyle) {
+    ADDED("ADDED", "fas fa-plus", ButtonStyle.INFO),
+    MISSING("MISSING", "fas fa-minus", ButtonStyle.DANGER),
+    DIFF("DIFF", "fas fa-bell", ButtonStyle.WARNING),
+    INFO("INFO", "fas fa-info-circle", ButtonStyle.OUTLINEINFO),
+    ERROR("ERROR", "fas fa-bug", ButtonStyle.OUTLINEDANGER),
+}
+
+class LogEntryComparison(val expected: LogEntry?, val actual: LogEntry?) {
+    var changeType: ChangeType
+    var iconName: String
+    var expectedResponse: String?
+    var actualResponse: String?
+
+    init {
+        if (expected == null && actual == null) {
+            throw Throwable("[LogEntryComparison.init] actual and expected not set")
+        } else {
+            changeType = compare()
+            iconName = changeType.iconName
+            expectedResponse = expected?.response
+            actualResponse = actual?.response
+        }
+    }
+
+    private fun compare(): ChangeType {
+        val responsesAreEqual = areResponsesEqual()
+        return when {
+            expected == null -> ChangeType.ADDED
+            actual == null -> ChangeType.MISSING
+            responsesAreEqual -> ChangeType.INFO
+            !responsesAreEqual -> ChangeType.DIFF
+            else -> ChangeType.ERROR
+        }
+    }
+
+    private fun areResponsesEqual(): Boolean {
+        val expectedBaseUrl: String = ""
+        val actualBaseUrl: String = "" //FIXME
+        val expected = expectedResponse?.replace(expectedBaseUrl, "")
+        val actual = actualResponse?.replace(actualBaseUrl, "")
+        return (expected == actual)
+    }
+
+}
\ No newline at end of file
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ReplayCommand.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ReplayCommand.kt
index 1a46437..4df6d24 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ReplayCommand.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ReplayCommand.kt
@@ -56,7 +56,7 @@ class ReplayCommand : Command() {
         val uiEvents = filterReplayEvents(expectedEvents)
         replay(uiEvents, urlUnderTest)
 
-        val title = "Replay Events: " + oldBaseUrl + " -> " + urlUnderTest
+        val title = "Replay Events: $oldBaseUrl -> $urlUnderTest"
         val rdd = ReplayDiffDialog(expectedEvents, title)
         rdd.dialog.open()
     }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/ColumnFactory.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/ColumnFactory.kt
index 0c18bf5..f0349a9 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/ColumnFactory.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/core/ColumnFactory.kt
@@ -41,7 +41,6 @@ class ColumnFactory {
     }
 
     fun buildColumns(displayCollection: CollectionDM): List<ColumnDefinition<dynamic>> {
-
         val columns = mutableListOf<ColumnDefinition<Exposer>>()
         addColumnForObjectIcon(displayCollection, columns)
         addColumnsForProperties(displayCollection, columns)
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/About.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/About.kt
index 2885f91..7f8bc70 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/About.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/About.kt
@@ -16,7 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.isis.client.kroviz.ui.dialog
 
 import org.apache.isis.client.kroviz.to.ValueType
@@ -25,14 +24,9 @@ import org.apache.isis.client.kroviz.ui.core.RoDialog
 import org.apache.isis.client.kroviz.utils.UUID
 
 class About : Command() {
-    var dialog: RoDialog
     private val formItems = mutableListOf<FormItem>()
     private val _LI = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
 
-    override fun open()  {
-        dialog.open()
-    }
-
     init {
         // see: https://upload.wikimedia.org/wikipedia/commons/6/6c/Trajans-Column-lower-animated.svg
         val fiImg = FormItem(
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ActionPrompt.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ActionPrompt.kt
index aafb462..5d8fbd5 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ActionPrompt.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ActionPrompt.kt
@@ -32,15 +32,13 @@ import org.apache.isis.client.kroviz.ui.core.RoDialog
 
 class ActionPrompt(val action: Action) : Command() {
 
-    private lateinit var form: RoDialog
-
     fun open(at: Point) {
         val formItems = buildFormItems()
-        form = RoDialog(
+        dialog = RoDialog(
                 caption = buildLabel(),
                 items = formItems,
                 command = this)
-        form.open(at)
+        dialog.open(at)
     }
 
     override fun execute(action:String?) {
@@ -81,11 +79,11 @@ class ActionPrompt(val action: Action) : Command() {
     }
 
     private fun extractUserInput(): Link {
-        //IMPROVE function has a side effect, ie. amends link with arguments
+        //IMPROVE function has a side effect, i.e. amends link with arguments
         val link = action.getInvokeLink()!!
         var value: String? = null
         var key: String? = null
-        val formPanel = form.formPanel
+        val formPanel = dialog.formPanel
         val kids = formPanel!!.getChildren()
         //iterate over FormItems (0,1) but not Buttons(2,3)
         for (i in kids) {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/Command.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/Command.kt
index 0daaad9..168c8dc 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/Command.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/Command.kt
@@ -21,15 +21,17 @@ package org.apache.isis.client.kroviz.ui.dialog
 import org.apache.isis.client.kroviz.core.aggregator.ActionDispatcher
 import org.apache.isis.client.kroviz.core.event.ResourceProxy
 import org.apache.isis.client.kroviz.to.Link
+import org.apache.isis.client.kroviz.ui.core.RoDialog
 
 abstract class Command {
+    lateinit var dialog: RoDialog
 
     open fun execute(action: String? = null) {
         // subclass responsibility
     }
 
     open fun open() {
-        // subclass responsibility
+        dialog.open()
     }
 
     fun invoke(link: Link) {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DiagramDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DiagramDialog.kt
index 623994d..7252338 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DiagramDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DiagramDialog.kt
@@ -32,11 +32,10 @@ class DiagramDialog(
 ) : Command() {
 
     private var callBack: Any = UUID()
-    private var dialog: RoDialog
     private val formItems = mutableListOf<FormItem>()
 
     override fun open() {
-        dialog.open()
+        super.open()
         UmlUtils.generateJsonDiagram(pumlCode, callBack)
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DownloadDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DownloadDialog.kt
index 043fb92..1d824b0 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DownloadDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DownloadDialog.kt
@@ -26,13 +26,12 @@ import org.apache.isis.client.kroviz.utils.DomUtil
 
 class DownloadDialog(val fileName:String, val content:String) : Command() {
 
-    private lateinit var form: RoDialog
     val formItems = mutableListOf<FormItem>()
 
     override fun open() {
         formItems.add(FormItem("Preview", ValueType.TEXT_AREA, content, 15))
-        form = RoDialog(caption = "Download: $fileName", items = formItems, command = this)
-        form.open()
+        dialog = RoDialog(caption = "Download: $fileName", items = formItems, command = this)
+        dialog.open()
     }
 
     override fun execute(action:String?) {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt
new file mode 100644
index 0000000..d5804f5
--- /dev/null
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.client.kroviz.ui.dialog
+
+import io.kvision.core.CssSize
+import io.kvision.core.UNIT
+import io.kvision.panel.VPanel
+import org.apache.isis.client.kroviz.core.event.LogEntryComparison
+import org.apache.isis.client.kroviz.ui.core.RoDialog
+import org.apache.isis.client.kroviz.ui.core.UiManager
+import org.apache.isis.client.kroviz.ui.panel.EventLogTable
+
+class EventCompareDialog(val data: List<LogEntryComparison>) : Command() {
+
+    private val panel = VPanel(spacing = 3) {
+        width = CssSize(100, UNIT.perc)
+    }
+
+    init {
+        dialog = RoDialog(
+            caption = "Event Comparison",
+            items = mutableListOf(),
+            command = this,
+            defaultAction = "Pin",
+            widthPerc = 60,
+            heightPerc = 70,
+        )
+        //FIXME -> reuse -> ColumnFactory and RoTable if possible
+        val table = EventLogTable(UiManager.getEventStore().log)
+        table.tabulator.addCssClass("tabulator-in-dialog")
+        panel.add(table)
+
+        dialog.formPanel!!.add(panel)
+    }
+
+    override fun execute(action: String?) {
+    }
+
+}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventDialog.kt
index 887d78c..49b172b 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventDialog.kt
@@ -30,8 +30,7 @@ import org.apache.isis.client.kroviz.ui.core.RoDialog
 import org.apache.isis.client.kroviz.ui.core.UiManager
 import org.apache.isis.client.kroviz.ui.panel.EventLogTable
 
-class EventDialog() : Command() {
-    var dialog: RoDialog
+class EventDialog : Command() {
 
     private val eventPanel = VPanel(spacing = 3) {
         width = CssSize(100, UNIT.perc)
@@ -84,7 +83,7 @@ class EventDialog() : Command() {
                 dialog.close()
             }
             action == REP -> {
-                LoginPrompt(ReplayCommand()).open()
+                LoginPrompt(nextCommand = ReplayCommand()).open()
                 dialog.close()
             }
             else -> {
@@ -92,8 +91,4 @@ class EventDialog() : Command() {
         }
     }
 
-    override fun open() {
-        dialog.open()
-    }
-
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventExportDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventExportDialog.kt
index 365fdaf..8eda5b1 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventExportDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventExportDialog.kt
@@ -28,15 +28,14 @@ import io.kvision.form.select.SimpleSelect
 import org.apache.isis.client.kroviz.ui.core.FormItem
 import org.apache.isis.client.kroviz.ui.core.UiManager
 
-class EventExportDialog() : Command() {
+class EventExportDialog : Command() {
 
-    private lateinit var form: RoDialog
     private var output: String = ""
     val formItems = mutableListOf<FormItem>()
     val events = mutableListOf<ReplayEvent>()
 
     private fun collectReplayEvents() {
-        UiManager.getEventStore().log.forEach { it ->
+        UiManager.getEventStore().log.forEach {
             val re = buildExportEvent(it)
             when (it.state) {
                 EventState.SUCCESS_JS -> events.add(re)
@@ -67,8 +66,7 @@ class EventExportDialog() : Command() {
             else -> {
             }
         }
-        val format = extractUserInput("Format")
-        when (format) {
+        when (extractUserInput("Format")) {
             "CSV" -> {
                 output = asCsv(events)
                 fileName += ".csv"
@@ -84,7 +82,7 @@ class EventExportDialog() : Command() {
     }
 
     private fun extractUserInput(fieldName: String): String? {
-        val formPanel = form.formPanel
+        val formPanel = dialog.formPanel
         val kids = formPanel!!.getChildren()
         //iterate over FormItems (0,1) but not Buttons(2,3)
         for (i in kids) {
@@ -102,7 +100,7 @@ class EventExportDialog() : Command() {
     }
 
     private fun collectUnfinishedEvents() {
-        UiManager.getEventStore().log.forEach { it ->
+        UiManager.getEventStore().log.forEach {
             val re = buildExportEvent(it)
             when (it.state) {
                 EventState.RUNNING -> events.add(re)
@@ -114,7 +112,7 @@ class EventExportDialog() : Command() {
     }
 
     private fun collectAllEvents() {
-        UiManager.getEventStore().log.forEach { it ->
+        UiManager.getEventStore().log.forEach {
             val re = buildExportEvent(it)
             events.add(re)
         }
@@ -131,8 +129,8 @@ class EventExportDialog() : Command() {
         filter.add(StringPair("UNFINISHED", "Unfinished"))
         formItems.add(FormItem("Filter", ValueType.SIMPLE_SELECT, filter))
 
-        form = RoDialog(caption = "Export", items = formItems, command = this)
-        form.open()
+        dialog = RoDialog(caption = "Export", items = formItems, command = this)
+        dialog.open()
     }
 
     private fun asCsv(events: MutableList<ReplayEvent>): String {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventImportDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventImportDialog.kt
index 0ae1366..b41085e 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventImportDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventImportDialog.kt
@@ -28,15 +28,14 @@ import io.kvision.form.select.SimpleSelect
 import org.apache.isis.client.kroviz.ui.core.FormItem
 import org.apache.isis.client.kroviz.ui.core.UiManager
 
-class EventImportDialog() : Command() {
+class EventImportDialog : Command() {
 
-    private lateinit var form: RoDialog
     private var output: String = ""
     val formItems = mutableListOf<FormItem>()
     val events = mutableListOf<ReplayEvent>()
 
     private fun collectReplayEvents() {
-        UiManager.getEventStore().log.forEach { it ->
+        UiManager.getEventStore().log.forEach {
             val re = buildExportEvent(it)
             when (it.state) {
                 EventState.SUCCESS_JS -> events.add(re)
@@ -67,8 +66,7 @@ class EventImportDialog() : Command() {
             else -> {
             }
         }
-        val format = extractUserInput("Format")
-        when (format) {
+        when (extractUserInput("Format")) {
             "CSV" -> {
                 output = asCsv(events)
                 fileName += ".csv"
@@ -84,7 +82,7 @@ class EventImportDialog() : Command() {
     }
 
     private fun extractUserInput(fieldName: String): String? {
-        val formPanel = form.formPanel
+        val formPanel = dialog.formPanel
         val kids = formPanel!!.getChildren()
         //iterate over FormItems (0,1) but not Buttons(2,3)
         for (i in kids) {
@@ -102,7 +100,7 @@ class EventImportDialog() : Command() {
     }
 
     private fun collectUnfinishedEvents() {
-        UiManager.getEventStore().log.forEach { it ->
+        UiManager.getEventStore().log.forEach {
             val re = buildExportEvent(it)
             when (it.state) {
                 EventState.RUNNING -> events.add(re)
@@ -114,7 +112,7 @@ class EventImportDialog() : Command() {
     }
 
     private fun collectAllEvents() {
-        UiManager.getEventStore().log.forEach { it ->
+        UiManager.getEventStore().log.forEach {
             val re = buildExportEvent(it)
             events.add(re)
         }
@@ -131,8 +129,8 @@ class EventImportDialog() : Command() {
         filter.add(StringPair("UNFINISHED", "Unfinished"))
         formItems.add(FormItem("Filter", ValueType.SIMPLE_SELECT, filter))
 
-        form = RoDialog(caption = "Export", items = formItems, command = this)
-        form.open()
+        dialog = RoDialog(caption = "Export", items = formItems, command = this)
+        dialog.open()
     }
 
     private fun asCsv(events: MutableList<ReplayEvent>): String {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt
index 8002a38..676c074 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt
@@ -33,13 +33,12 @@ import org.apache.isis.client.kroviz.utils.Flatted
 import org.apache.isis.client.kroviz.utils.StringUtils
 import org.apache.isis.client.kroviz.utils.XmlHelper
 
-class EventLogDetail(val logEntryFromTabulator: LogEntry) : Command() {
+class EventLogDetail(logEntryFromTabulator: LogEntry) : Command() {
     private var logEntry: LogEntry
-    private lateinit var dialog: RoDialog
 
     init {
         // For a yet unknown reason, aggregators are not transmitted via tabulator.
-        // As a WORKAROUND, we fetch the full blown LogEntry from the EventStore again.
+        // As a WORKAROUND, we fetch the full-blown LogEntry from the EventStore again.
         val rs = ResourceSpecification(logEntryFromTabulator.title)
         logEntry = UiManager.getEventStore().findBy(rs) ?: logEntryFromTabulator  // in case of xml, we use the entry passed in
     }
@@ -90,7 +89,7 @@ class EventLogDetail(val logEntryFromTabulator: LogEntry) : Command() {
             }
             else -> {
                 console.log(logEntry)
-                console.log("Action not defined yet: " + action)
+                console.log("Action not defined yet: $action")
             }
         }
     }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/LoginPrompt.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/LoginPrompt.kt
index b55e5f8..081aa52 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/LoginPrompt.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/LoginPrompt.kt
@@ -32,8 +32,6 @@ import org.apache.isis.client.kroviz.ui.core.UiManager
 
 class LoginPrompt(val nextCommand: Command? = null) : Command() {
 
-    private lateinit var form: RoDialog
-
     //Default values
     private var url = Constants.demoUrl
     private var username = Constants.demoUser
@@ -47,9 +45,9 @@ class LoginPrompt(val nextCommand: Command? = null) : Command() {
         formItems.add(FormItem("Url", ValueType.SIMPLE_SELECT, urlList))
         formItems.add(FormItem("User", ValueType.TEXT, username))
         formItems.add(FormItem("Password", ValueType.PASSWORD, password))
-        form = RoDialog(caption = "Connect", items = formItems, command = this, heightPerc = 27)
+        dialog = RoDialog(caption = "Connect", items = formItems, command = this, heightPerc = 27)
         val at = UiManager.position!!
-        form.open(at)
+        dialog.open(at)
     }
 
     override fun execute(action: String?) {
@@ -61,14 +59,14 @@ class LoginPrompt(val nextCommand: Command? = null) : Command() {
             UiManager.login(url, username, password)
             val link = Link(href = url + Constants.restInfix)
             invoke(link)
-            UiManager.closeDialog(form)
+            UiManager.closeDialog(dialog)
         }
     }
 
     private fun extractUserInput() {
         //TODO function has a side effect, ie. changes variable values
         var key: String?
-        val formPanel = form.formPanel
+        val formPanel = dialog.formPanel
         val kids = formPanel!!.getChildren()
         //iterate over FormItems (0,1,2) but not Buttons(3,4)
         for (i in kids) {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/NotificationDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/NotificationDialog.kt
index bde8185..b03f86f 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/NotificationDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/NotificationDialog.kt
@@ -21,7 +21,6 @@ package org.apache.isis.client.kroviz.ui.dialog
 import org.apache.isis.client.kroviz.to.ValueType
 import org.apache.isis.client.kroviz.ui.core.FormItem
 import org.apache.isis.client.kroviz.ui.core.RoDialog
-import org.apache.isis.client.kroviz.ui.core.RoStatusBar
 import org.apache.isis.client.kroviz.ui.core.UiManager
 
 class NotificationDialog(val message: String) : Command() {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ReplayDiffDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ReplayDiffDialog.kt
index 55d3a85..c5d0a68 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ReplayDiffDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ReplayDiffDialog.kt
@@ -25,8 +25,10 @@ import io.kvision.core.UNIT
 import io.kvision.panel.Direction
 import io.kvision.panel.SplitPanel
 import io.kvision.panel.VPanel
-import org.apache.isis.client.kroviz.core.event.EventState
+import io.kvision.state.ObservableList
+import org.apache.isis.client.kroviz.core.event.EventStore
 import org.apache.isis.client.kroviz.core.event.LogEntry
+import org.apache.isis.client.kroviz.core.event.LogEntryComparison
 import org.apache.isis.client.kroviz.core.event.ResourceSpecification
 import org.apache.isis.client.kroviz.ui.core.RoDialog
 import org.apache.isis.client.kroviz.ui.core.UiManager
@@ -36,7 +38,6 @@ class ReplayDiffDialog(
     private val expectedEvents: List<LogEntry>,
     title: String
 ) : Command() {
-    var dialog: RoDialog
 
     private val expectedPanel = VPanel(spacing = 3) {
         width = CssSize(20, UNIT.perc)
@@ -73,19 +74,26 @@ class ReplayDiffDialog(
     }
 
     override fun execute(action: String?) {
-        // iterate over expected and set each status to DIFF, where responses don't match
-        expectedEvents.forEach { xp ->
-            val rs = ResourceSpecification(xp.url, xp.subType)
-            val actual = UiManager.getEventStore().findBy(rs)
-            if (actual != null) {
-                val isSame = actual.response == xp.response
-                if (!isSame) {
-                    xp.state = EventState.DIFF
-                }
-            } else {
-                xp.state = EventState.DIFF
-            }
+        val comparisons = mutableListOf<LogEntryComparison>()
+        // first pass: iterate over expected
+        val actualStore = UiManager.getEventStore()
+        expectedEvents.forEach {
+            val rs = ResourceSpecification(it.url, it.subType)
+            val actualEvent: LogEntry? = actualStore.findBy(rs)
+            comparisons.add(LogEntryComparison(it, actualEvent))
         }
+
+        // second pass: iterate over actual
+        val actualEvents = actualStore.log
+        val expectedStore = EventStore()
+        expectedStore.log = expectedEvents as ObservableList<LogEntry>
+        actualEvents.forEach {
+            val rs = ResourceSpecification(it.url, it.subType)
+            val expectedEvent = expectedStore.findBy(rs)
+            //TODO check for duplicates?
+            comparisons.add(LogEntryComparison(expectedEvent, it))
+        }
+        EventCompareDialog(comparisons).open()
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/SvgInline.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/SvgInline.kt
index 1343af8..03f142c 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/SvgInline.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/SvgInline.kt
@@ -16,7 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.isis.client.kroviz.ui.dialog
 
 import org.apache.isis.client.kroviz.core.aggregator.SvgDispatcher
@@ -29,13 +28,8 @@ import org.apache.isis.client.kroviz.ui.core.RoDialog
 import org.apache.isis.client.kroviz.utils.UUID
 
 class SvgInline : Command() {
-    private var dialog: RoDialog
     private val formItems = mutableListOf<FormItem>()
 
-    override fun open() {
-        dialog.open()
-    }
-
     init {
         val callBack = UUID()
         val fiImg = FormItem(
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/UndefinedDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/UndefinedDialog.kt
index f362aa2..7621fef 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/UndefinedDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/UndefinedDialog.kt
@@ -25,7 +25,7 @@ import org.apache.isis.client.kroviz.ui.core.RoDialog
 
 class UndefinedDialog(val logEntry: LogEntry) : Command() {
 
-    val instruction = """1. Create a ResponseClass under test/kotlin/org.ro.urls with
+    private val instruction = """1. Create a ResponseClass under test/kotlin/org.ro.urls with
     - url 
     - str (JSON)
 2. Create a TestCase under test/kotlin/org.ro.to

[isis] 05/06: ISIS-2348 EventComparison works

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

joergrade pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit b1bf26066b18a794dbf04279506796bd69be7f3c
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Mon Nov 22 20:34:24 2021 +0100

    ISIS-2348 EventComparison works
---
 .../isis/client/kroviz/core/event/EventStore.kt    |  5 +++
 .../client/kroviz/core/event/LogEntryComparison.kt | 28 +++++++-----
 .../isis/client/kroviz/core/event/ReplayCommand.kt |  4 +-
 .../apache/isis/client/kroviz/ui/core/RoMenuBar.kt | 23 ----------
 .../client/kroviz/ui/diagram/LinkTreeDiagram.kt    |  4 +-
 .../client/kroviz/ui/dialog/EventCompareDialog.kt  |  9 ++--
 .../{ReplayDiffDialog.kt => EventReplayDialog.kt}  | 28 +++++++-----
 ...ompareDialog.kt => ResponseComparisonDialog.kt} | 41 ++++++++++-------
 .../client/kroviz/ui/panel/EventComparisonTable.kt | 51 ++++++++++------------
 .../apache/isis/client/kroviz/utils/StringUtils.kt |  5 ++-
 .../isis/client/kroviz/util/StringUtilsTest.kt     |  2 +-
 11 files changed, 97 insertions(+), 103 deletions(-)

diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/EventStore.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/EventStore.kt
index a0ae52b..eb8eab8 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/EventStore.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/EventStore.kt
@@ -26,6 +26,7 @@ import org.apache.isis.client.kroviz.to.HasLinks
 import org.apache.isis.client.kroviz.to.TObject
 import org.apache.isis.client.kroviz.to.mb.Menubars
 import org.apache.isis.client.kroviz.ui.core.UiManager
+import org.apache.isis.client.kroviz.utils.StringUtils
 import org.apache.isis.client.kroviz.utils.UUID
 import org.w3c.files.Blob
 
@@ -150,6 +151,10 @@ class EventStore {
         }
     }
 
+    fun findBy(shortTitle: String): LogEntry? {
+        return log.firstOrNull { StringUtils.shortTitle(it.title) == shortTitle }
+    }
+
     fun findBy(aggregator: BaseAggregator): LogEntry? {
         return log.firstOrNull { it.getAggregator() == aggregator }
     }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryComparison.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryComparison.kt
index 37119b9..d8825f1 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryComparison.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryComparison.kt
@@ -20,6 +20,7 @@ package org.apache.isis.client.kroviz.core.event
 
 import io.kvision.html.ButtonStyle
 import kotlinx.serialization.Serializable
+import org.apache.isis.client.kroviz.ui.core.Constants
 
 enum class ChangeType(val id: String, val iconName: String, val style: ButtonStyle) {
     ADDED("ADDED", "fas fa-plus", ButtonStyle.INFO),
@@ -30,12 +31,14 @@ enum class ChangeType(val id: String, val iconName: String, val style: ButtonSty
 }
 
 @Serializable
-data class LogEntryComparison(val expected: LogEntry?, val actual: LogEntry?) {
+data class LogEntryComparison(val title: String, val expected: LogEntry?, val actual: LogEntry?) {
     var changeType: ChangeType
-    var title: String
     var iconName: String
     var expectedResponse: String? = null
     var actualResponse: String? = null
+    var expectedBaseUrl = ""
+    var actualBaseUrl = ""
+
 
     init {
         if (expected == null && actual == null) {
@@ -43,17 +46,22 @@ data class LogEntryComparison(val expected: LogEntry?, val actual: LogEntry?) {
         } else {
             changeType = compare()
             iconName = changeType.iconName
-            if (expected == null) {
-                actualResponse = actual?.response
-                title = actual?.title.toString()
-            } else {
-                expectedResponse = expected.response
-                title = expected.title
+            actualResponse = actual?.response
+            expectedResponse = expected?.response
+            if (expected != null) {
+                expectedBaseUrl = extractBaseUrl(expected)
+            }
+            if (actual != null) {
+                actualBaseUrl = extractBaseUrl(actual)
             }
-
         }
     }
 
+    private fun extractBaseUrl(event: LogEntry): String {
+        val title = event.title
+        return title.split(Constants.restInfix).first()
+    }
+
     private fun compare(): ChangeType {
         val responsesAreEqual = areResponsesEqual()
         return when {
@@ -66,8 +74,6 @@ data class LogEntryComparison(val expected: LogEntry?, val actual: LogEntry?) {
     }
 
     private fun areResponsesEqual(): Boolean {
-        val expectedBaseUrl = ""
-        val actualBaseUrl = "" //FIXME
         val expected = expectedResponse?.replace(expectedBaseUrl, "")
         val actual = actualResponse?.replace(actualBaseUrl, "")
         return (expected == actual)
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ReplayCommand.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ReplayCommand.kt
index 4df6d24..3cc1997 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ReplayCommand.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ReplayCommand.kt
@@ -30,7 +30,7 @@ import org.apache.isis.client.kroviz.to.TObject
 import org.apache.isis.client.kroviz.ui.core.Constants
 import org.apache.isis.client.kroviz.ui.core.UiManager
 import org.apache.isis.client.kroviz.ui.dialog.Command
-import org.apache.isis.client.kroviz.ui.dialog.ReplayDiffDialog
+import org.apache.isis.client.kroviz.ui.dialog.EventReplayDialog
 
 val AppScope = CoroutineScope(window.asCoroutineDispatcher())
 
@@ -57,7 +57,7 @@ class ReplayCommand : Command() {
         replay(uiEvents, urlUnderTest)
 
         val title = "Replay Events: $oldBaseUrl -> $urlUnderTest"
-        val rdd = ReplayDiffDialog(expectedEvents, title)
+        val rdd = EventReplayDialog(expectedEvents, title)
         rdd.dialog.open()
     }
 
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 cb11e4d..7c636ee 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
@@ -21,14 +21,11 @@ package org.apache.isis.client.kroviz.ui.core
 import io.kvision.core.CssSize
 import io.kvision.core.UNIT
 import io.kvision.dropdown.DropDown
-import io.kvision.html.Button
 import io.kvision.html.ButtonStyle
 import io.kvision.html.Link
 import io.kvision.navbar.*
 import io.kvision.panel.SimplePanel
 import io.kvision.panel.vPanel
-import kotlinx.browser.window
-import org.apache.isis.client.kroviz.core.event.ReplayCommand
 import org.apache.isis.client.kroviz.to.mb.Menubars
 import org.apache.isis.client.kroviz.ui.chart.SampleChartModel
 import org.apache.isis.client.kroviz.ui.dialog.About
@@ -50,7 +47,6 @@ class RoMenuBar : SimplePanel() {
                 marginLeft = CssSize(-32, UNIT.px)
                 height = CssSize(40, UNIT.px)
                 nav = nav()
-//                logoButton() leaves an empty space here without network connection
                 val mainEntry = buildMainMenu()
                 nav.add(mainEntry)
             }
@@ -86,14 +82,6 @@ class RoMenuBar : SimplePanel() {
             buildMenuEntry("Events", "Event", { EventDialog().open() })
         )
 
-        mainMenu.add(
-            buildMenuEntry("Replay", "Replay", {  })
-        )
-
-        mainMenu.add(
-            buildMenuEntry("Event Log", "History", { UiManager.add("Event Log", EventLogTable(UiManager.getEventStore().log)) })
-        )
-
         val chartTitle = "Sample Chart"
         mainMenu.add(
             buildMenuEntry(chartTitle, "Chart", { UiManager.add(chartTitle, EventChart(SampleChartModel())) })
@@ -128,7 +116,6 @@ class RoMenuBar : SimplePanel() {
     }
 
     fun amendMenu(menuBars: Menubars) {
-        //       logoButton()
         menuBars.primary.menu.forEach { m ->
             val dd = MenuFactory.buildForMenu(m)
             if (dd.getChildren().isNotEmpty()) nav.add(dd)
@@ -137,14 +124,4 @@ class RoMenuBar : SimplePanel() {
         nav.add(MenuFactory.buildForMenu(menuBars.tertiary.menu.first()))
     }
 
-    private fun logoButton() {
-        val classNames = "isis-logo-button-image logo-button"
-        val logo = Button("", style = ButtonStyle.LINK)
-        logo.addCssClass(classNames)
-        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/diagram/LinkTreeDiagram.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/LinkTreeDiagram.kt
index 80b8a10..1e80749 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/LinkTreeDiagram.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/LinkTreeDiagram.kt
@@ -50,7 +50,7 @@ object LinkTreeDiagram {
         val le = UiManager.getEventStore().findBy(rs)
         val pc = PumlCode()
         if (le != null) {
-            val title = StringUtils.shortTitle(url, protocolHostPort)
+            val title = StringUtils.shortTitle(url)
             pc.addStereotype(le.type)
             pc.addLink(url, title)
             pc.addHorizontalLine()
@@ -78,7 +78,7 @@ object LinkTreeDiagram {
                 obj.links.forEach {
                     if (it.relation() != Relation.SELF) {
                         val url = it.href
-                        val title = StringUtils.shortTitle(url, protocolHostPort)
+                        val title = StringUtils.shortTitle(url)
                         pc.addLink(url, title)
                     }
                 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt
index 2f4c960..8a64691 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt
@@ -16,7 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.isis.client.kroviz.ui.dialog
 
 import io.kvision.core.CssSize
@@ -27,6 +26,7 @@ import org.apache.isis.client.kroviz.ui.core.RoDialog
 import org.apache.isis.client.kroviz.ui.panel.EventComparisonTable
 
 class EventCompareDialog(val data: List<LogEntryComparison>) : Command() {
+    private var table: EventComparisonTable
 
     private val panel = VPanel(spacing = 3) {
         width = CssSize(100, UNIT.perc)
@@ -41,15 +41,12 @@ class EventCompareDialog(val data: List<LogEntryComparison>) : Command() {
             widthPerc = 60,
             heightPerc = 70,
         )
-        //FIXME -> reuse -> ColumnFactory and RoTable if possible
-        val table = EventComparisonTable(data)
+        //IMPROVE: reuse ColumnFactory and RoTable if possible
+        table = EventComparisonTable(data)
         table.tabulator.addCssClass("tabulator-in-dialog")
         panel.add(table)
 
         dialog.formPanel!!.add(panel)
     }
 
-    override fun execute(action: String?) {
-    }
-
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ReplayDiffDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventReplayDialog.kt
similarity index 76%
rename from incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ReplayDiffDialog.kt
rename to incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventReplayDialog.kt
index 7f4a20e..3a1fdc9 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ReplayDiffDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventReplayDialog.kt
@@ -25,7 +25,6 @@ import io.kvision.core.UNIT
 import io.kvision.panel.Direction
 import io.kvision.panel.SplitPanel
 import io.kvision.panel.VPanel
-import io.kvision.state.ObservableList
 import org.apache.isis.client.kroviz.core.event.EventStore
 import org.apache.isis.client.kroviz.core.event.LogEntry
 import org.apache.isis.client.kroviz.core.event.LogEntryComparison
@@ -33,8 +32,9 @@ import org.apache.isis.client.kroviz.core.event.ResourceSpecification
 import org.apache.isis.client.kroviz.ui.core.RoDialog
 import org.apache.isis.client.kroviz.ui.core.UiManager
 import org.apache.isis.client.kroviz.ui.panel.EventLogTable
+import org.apache.isis.client.kroviz.utils.StringUtils
 
-class ReplayDiffDialog(
+class EventReplayDialog(
     private val expectedEvents: List<LogEntry>,
     title: String
 ) : Command() {
@@ -74,13 +74,14 @@ class ReplayDiffDialog(
     }
 
     override fun execute(action: String?) {
-        val comparisons = mutableListOf<LogEntryComparison>()
+        val comparisonMap = mutableMapOf<String, LogEntryComparison>()
         // first pass: iterate over expected
         val actualStore = UiManager.getEventStore()
         expectedEvents.forEach {
-            val rs = ResourceSpecification(it.url, it.subType)
-            val actualEvent: LogEntry? = actualStore.findBy(rs)
-            comparisons.add(LogEntryComparison(it, actualEvent))
+            val shortTitle = StringUtils.shortTitle(it.title)
+            val actualEvent: LogEntry? = actualStore.findBy(shortTitle)
+            val lec = LogEntryComparison(shortTitle, it, actualEvent)
+            comparisonMap.put(shortTitle, lec)
         }
 
         // second pass: iterate over actual
@@ -88,12 +89,17 @@ class ReplayDiffDialog(
         val expectedStore = EventStore()
         expectedStore.log.addAll(expectedEvents)
         actualEvents.forEach {
-            val rs = ResourceSpecification(it.url, it.subType)
-            val expectedEvent = expectedStore.findBy(rs)
-            //TODO check for duplicates?
-            comparisons.add(LogEntryComparison(expectedEvent, it))
+            val shortTitle = StringUtils.shortTitle(it.title)
+            if (!comparisonMap.contains(shortTitle)) {
+                val rs = ResourceSpecification(it.url, it.subType)
+                val expectedEvent = expectedStore.findBy(rs)
+                val lec = LogEntryComparison(shortTitle, expectedEvent, it)
+                comparisonMap.put(shortTitle, lec)
+            }
         }
-        EventCompareDialog(comparisons).open()
+        val comparisonList = mutableListOf<LogEntryComparison>()
+        comparisonList.addAll(comparisonMap.values)
+        EventCompareDialog(comparisonList).open()
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ResponseComparisonDialog.kt
similarity index 52%
copy from incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt
copy to incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ResponseComparisonDialog.kt
index 2f4c960..7ab8970 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventCompareDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ResponseComparisonDialog.kt
@@ -16,40 +16,49 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.isis.client.kroviz.ui.dialog
 
 import io.kvision.core.CssSize
+import io.kvision.core.FlexDirection
 import io.kvision.core.UNIT
+import io.kvision.form.text.TextArea
+import io.kvision.panel.Direction
+import io.kvision.panel.SplitPanel
 import io.kvision.panel.VPanel
 import org.apache.isis.client.kroviz.core.event.LogEntryComparison
 import org.apache.isis.client.kroviz.ui.core.RoDialog
-import org.apache.isis.client.kroviz.ui.panel.EventComparisonTable
 
-class EventCompareDialog(val data: List<LogEntryComparison>) : Command() {
+class ResponseComparisonDialog(obj: LogEntryComparison) : Command() {
+    private val title = "Response Diff"
 
-    private val panel = VPanel(spacing = 3) {
-        width = CssSize(100, UNIT.perc)
+    private val expectedPanel = VPanel(spacing = 3) {
+        width = CssSize(50, UNIT.perc)
+    }
+    private val actualPanel = VPanel(spacing = 3) {
+        width = CssSize(50, UNIT.perc)
     }
 
     init {
         dialog = RoDialog(
-            caption = "Event Comparison",
+            caption = title,
             items = mutableListOf(),
             command = this,
-            defaultAction = "Pin",
-            widthPerc = 60,
+            widthPerc = 80,
             heightPerc = 70,
+            customButtons = mutableListOf()
         )
-        //FIXME -> reuse -> ColumnFactory and RoTable if possible
-        val table = EventComparisonTable(data)
-        table.tabulator.addCssClass("tabulator-in-dialog")
-        panel.add(table)
-
-        dialog.formPanel!!.add(panel)
-    }
+        val expectedText = TextArea(label = "Expected", value = obj.expectedResponse, rows = 30)
+        expectedPanel.add(expectedText)
+        val actualText = TextArea(label = "Actual", value = obj.actualResponse, rows = 30)
+        actualPanel.add(actualText)
 
-    override fun execute(action: String?) {
+        val splitPanel = SplitPanel(direction = Direction.VERTICAL)
+        splitPanel.addCssClass("dialog-content")
+        splitPanel.flexDirection = FlexDirection.ROW
+        splitPanel.add(expectedPanel)
+        splitPanel.add(actualPanel)
+        dialog.formPanel!!.add(splitPanel)
+        dialog.open()
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventComparisonTable.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventComparisonTable.kt
index d58c8c1..f350921 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventComparisonTable.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/panel/EventComparisonTable.kt
@@ -20,17 +20,13 @@ package org.apache.isis.client.kroviz.ui.panel
 
 import io.kvision.core.*
 import io.kvision.html.Button
-import io.kvision.html.ButtonStyle
 import io.kvision.panel.VPanel
 import io.kvision.panel.hPanel
 import io.kvision.tabulator.*
 import io.kvision.utils.px
-import org.apache.isis.client.kroviz.core.event.LogEntry
 import org.apache.isis.client.kroviz.core.event.LogEntryComparison
-import org.apache.isis.client.kroviz.to.TObject
 import org.apache.isis.client.kroviz.ui.core.Constants
-import org.apache.isis.client.kroviz.ui.dialog.EventLogDetail
-import org.apache.isis.client.kroviz.utils.StringUtils
+import org.apache.isis.client.kroviz.ui.dialog.ResponseComparisonDialog
 
 class EventComparisonTable(val model: List<LogEntryComparison>) : VPanel() {
     val tabulator: Tabulator<LogEntryComparison>
@@ -41,58 +37,46 @@ class EventComparisonTable(val model: List<LogEntryComparison>) : VPanel() {
             title = "",
             field = "changeType",
             width = "50",
-   //         headerMenu = DynamicMenuBuilder().buildTableMenu(this),
             hozAlign = Align.CENTER,
             vertAlign = VAlign.MIDDLE,
             formatterComponentFunction = { _, _, data -> buildActionButton(data) }
         ),
         ColumnDefinition(
             download = false,
+            title = "Status",
+            field = "changeType",
+            headerFilter = Editor.INPUT,
+            width = "100",
+        ),
+        ColumnDefinition(
+            download = false,
             title = "Title",
             field = "title",
             headerFilter = Editor.INPUT,
-            width = "200",
-            formatterComponentFunction = { _, _, data -> buildObjectButton(data) }
+            width = "700",
         ),
         ColumnDefinition(
             download = false,
-            title = "expectedResponse",
+            title = "Expected Response",
             field = "expectedResponse",
             headerFilter = Editor.INPUT,
-            width = "400",
+            width = "150",
         ),
         ColumnDefinition(
             download = false,
-            title = "actualResponse",
+            title = "Actual Response",
             field = "actualResponse",
             headerFilter = Editor.INPUT,
-            width = "400",
+            width = "150",
         )
     )
 
-    private fun buildObjectButton(data: LogEntryComparison): Button {
-        val b = Button(
-            text = StringUtils.shorten(data.title),
-            icon = data.changeType.iconName,
-            style = ButtonStyle.LINK
-        )
-        b.onClick {
-            kotlinx.browser.window.open(data.title) //IMPROVE should be URL
-        }
-        //val tto = TooltipOptions(title = data.title)
-        // tabulator tooltip is buggy: often the tooltip doesn't go away and the color is not settable
-        //b.enableTooltip(tto)
-    //    if (data.obj is TObject) b.setDragDropData(Constants.stdMimeType, data.url)
-        return b
-    }
-
     private fun buildActionButton(data: LogEntryComparison): Button {
         val b = Button(
             text = "",
             icon = "fa fa-info-circle",
             style = data.changeType.style
         )
-//        b.onClick { EventLogDetail(data).open() }
         b.margin = CssSize(-10, UNIT.px)
         b.addCssClass("btn-sm")
         return b
@@ -117,6 +101,15 @@ class EventComparisonTable(val model: List<LogEntryComparison>) : VPanel() {
 
         tabulator = tabulator(model, options = options) {
             setEventListener<Tabulator<LogEntryComparison>> {
+                cellClickTabulator = {
+                    // can't check cast to external interface
+                    val cc = it.detail as io.kvision.tabulator.js.Tabulator.CellComponent
+                    val column = cc.getColumn().getField()
+                    if (column == "changeType") {
+                        val obj = cc.getData() as LogEntryComparison
+                        ResponseComparisonDialog(obj).open()
+                    }
+                }
             }
         }
     }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/StringUtils.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/StringUtils.kt
index e2e77e8..a27637a 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/StringUtils.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/StringUtils.kt
@@ -64,9 +64,10 @@ object StringUtils {
         return if (input == outputWithoutWhiteSpace) input else output
     }
 
-    fun shortTitle(url: String, protocolHostPort: String): String {
-        var title = url
+    fun shortTitle(url: String): String {
         val signature = Constants.restInfix
+        val protocolHostPort = url.split(signature).first()
+        var title = url
         if (title.contains(signature)) {
             // strip off protocol, host, port
             title = title.replace(protocolHostPort + signature, "")
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/util/StringUtilsTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/util/StringUtilsTest.kt
index 9536a9d..e545aee 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/util/StringUtilsTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/util/StringUtilsTest.kt
@@ -20,7 +20,7 @@ class StringUtilsTest {
         assertTrue(protocolHostPort.startsWith("http://"))
 
         // when
-        val actual = StringUtils.shortTitle(url, protocolHostPort)
+        val actual = StringUtils.shortTitle(url)
         // then
         val expected = "/domain-types/demo.JavaLangStrings/collections/entities"
         assertEquals(expected, actual)

[isis] 01/06: ISIS-2348 HttpError interface name changed

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

joergrade pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 3f0aff04dc7b8d30a96392a55dd563e0833dd3b0
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Sun Nov 14 11:15:16 2021 +0100

    ISIS-2348 HttpError interface name changed
---
 .../apache/isis/client/kroviz/core/aggregator/ErrorDispatcher.kt    | 5 ++---
 .../kotlin/org/apache/isis/client/kroviz/to/PlainTransferObjects.kt | 6 +++---
 .../kotlin/org/apache/isis/client/kroviz/ui/dialog/ErrorDialog.kt   | 6 ++----
 3 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ErrorDispatcher.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ErrorDispatcher.kt
index 5b595c7..6b3a17c 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ErrorDispatcher.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ErrorDispatcher.kt
@@ -20,15 +20,14 @@ package org.apache.isis.client.kroviz.core.aggregator
 
 import org.apache.isis.client.kroviz.core.event.LogEntry
 import org.apache.isis.client.kroviz.core.event.ResourceSpecification
-import org.apache.isis.client.kroviz.to.HttpError
-import org.apache.isis.client.kroviz.to.HttpResponse
+import org.apache.isis.client.kroviz.to.HttpErrorResponse
 import org.apache.isis.client.kroviz.ui.core.UiManager
 import org.apache.isis.client.kroviz.ui.dialog.ErrorDialog
 
 class ErrorDispatcher : BaseAggregator() {
 
     override fun update(logEntry: LogEntry, subType: String) {
-        val error = logEntry.getTransferObject() as HttpResponse
+        val error = logEntry.getTransferObject() as HttpErrorResponse
         val url = logEntry.url
         val message = error.getMessage()
         val reSpec = ResourceSpecification(url)
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/PlainTransferObjects.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/PlainTransferObjects.kt
index c9e6d14..96c02b6 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/PlainTransferObjects.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/PlainTransferObjects.kt
@@ -34,7 +34,7 @@ data class DomainTypes(override val links: List<Link> = emptyList(),
                        val extensions: Extensions? = null
 ) : TransferObject, HasLinks
 
-interface HttpResponse {
+interface HttpErrorResponse {
     val detail: HttpErrorDetail?
     fun getMessage(): String
     fun getStatusCode(): Int
@@ -45,7 +45,7 @@ data class HttpError(
     private val httpStatusCode: Int,
     private val message: String,
     override val detail: HttpErrorDetail? = null
-) : TransferObject, HttpResponse {
+) : TransferObject, HttpErrorResponse {
     override fun getMessage() : String {
         return message
     }
@@ -69,7 +69,7 @@ data class Http401Error(
     private val error: String,
     private val path: String,
     override val detail: HttpErrorDetail? = null
-) : TransferObject, HttpResponse {
+) : TransferObject, HttpErrorResponse {
     override fun getMessage(): String {
         return error + " / " + path + " / " + timestamp
     }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ErrorDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ErrorDialog.kt
index 1015516..adf7658 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ErrorDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ErrorDialog.kt
@@ -19,9 +19,7 @@
 package org.apache.isis.client.kroviz.ui.dialog
 
 import org.apache.isis.client.kroviz.core.event.LogEntry
-import org.apache.isis.client.kroviz.to.Http401Error
-import org.apache.isis.client.kroviz.to.HttpError
-import org.apache.isis.client.kroviz.to.HttpResponse
+import org.apache.isis.client.kroviz.to.HttpErrorResponse
 import org.apache.isis.client.kroviz.to.ValueType
 import org.apache.isis.client.kroviz.ui.core.FormItem
 import org.apache.isis.client.kroviz.ui.core.RoDialog
@@ -29,7 +27,7 @@ import org.apache.isis.client.kroviz.ui.core.RoDialog
 class ErrorDialog(val logEntry: LogEntry) : Command() {
 
     fun open() {
-        val error = logEntry.getTransferObject() as HttpResponse
+        val error = logEntry.getTransferObject() as HttpErrorResponse
         val formItems = mutableListOf<FormItem>()
         formItems.add(FormItem("URL", ValueType.TEXT, logEntry.url))
         formItems.add(FormItem("Message", ValueType.TEXT, error.getMessage()))

[isis] 06/06: Merge branch 'master' of https://github.com/apache/isis

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

joergrade pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 2f7a53e7ec9d77591ca679715983405cfaf95fc1
Merge: b1bf260 18c690f
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Mon Nov 22 20:34:34 2021 +0100

    Merge branch 'master' of https://github.com/apache/isis

 .../modules/ROOT/pages/2021/2.0.0-M7/mignotes.adoc |   3 +
 .../java/org/apache/isis/applib/Identifier.java    |   6 -
 .../isis/applib/annotation/ValueSemantics.java     |   2 +-
 .../isis/applib/jaxb/JodaTimeJaxbAdapters.java     | 174 -----------
 .../isis/applib/services/command/Command.java      |   2 -
 .../applib/services/wrapper/WrapperFactory.java    |   8 +-
 .../org/apache/isis/applib/spec/package-info.java  |   2 +-
 .../org/apache/isis/applib/util/package-info.java  |   2 +-
 .../isis/applib/util/schema/CommonDtoUtils.java    |  27 +-
 .../applib/util/schema/InteractionDtoUtils.java    |   2 +-
 .../schema/_JodaTimeHelper.java}                   |  26 +-
 .../org/apache/isis/applib/value/package-info.java |   2 +-
 .../semantics}/DefaultsProvider.java               |   2 +-
 .../semantics}/EncoderDecoder.java                 |   2 +-
 .../semantics}/EncodingException.java              |   2 +-
 .../{adapters => value/semantics}/Parser.java      |   8 +-
 .../semantics}/ParsingException.java               |   2 +-
 .../{adapters => value/semantics}/Renderer.java    |   2 +-
 .../value/semantics}/TemporalValueSemantics.java   |  10 +-
 .../semantics}/ValueSemanticsAbstract.java         | 110 ++++++-
 .../semantics}/ValueSemanticsProvider.java         |   8 +-
 .../semantics/ValueSemanticsResolver.java}         |  16 +-
 .../semantics}/package-info.java                   |   8 +-
 .../org/apache/isis/applib/IdentifierTests.java    |  28 +-
 .../apache/isis/applib/util/schema/Roundtrip.java  |  26 +-
 .../resources/org/apache/isis/schema/bindings.xml  |   3 +-
 .../org/apache/isis/schema/cmd/cmd-2.0.xsd         |   3 +-
 .../org/apache/isis/schema/common/common-2.0.xsd   |  45 ++-
 .../commons/internal/functions/_Functions.java     |  61 +++-
 .../isis/commons/internal/reflection/_Reflect.java |   6 +
 .../commons/internal/reflection/ReflectTest.java   |  26 +-
 .../apache/isis/core/config/IsisConfiguration.java |   7 +
 .../core/config/beans/IsisBeanTypeRegistry.java    |   2 +-
 .../config/valuetypes/ValueSemanticsRegistry.java  |   2 +-
 core/jdk-supplemental/pom.xml                      |   2 +-
 core/metamodel/pom.xml                             |   2 +-
 .../core/metamodel/IsisModuleCoreMetamodel.java    |  15 +-
 .../_testing/MetaModelContext_forTesting.java      |   9 +-
 .../metamodel/commons/ScalarRepresentation.java    |  38 ++-
 .../isis/core/metamodel/facetapi/FacetHolder.java  |   2 +-
 .../actions/action/invocation/CommandUtil.java     |  49 +++-
 ...CssClassFaFacetOnMemberFromConfiguredRegex.java |  28 +-
 .../CssClassFaFacetOnMemberPostProcessor.java      |  14 +-
 .../publish/command/CommandPublishingFacet.java    |   3 +-
 .../object/defaults/DefaultedFacetAbstract.java    |   2 +-
 .../DefaultedFacetUsingDefaultsProvider.java       |   2 +-
 .../facets/object/encodeable/EncodableFacet.java   |   2 +-
 .../object/encodeable/EncoderDecoderUtil.java      |   2 +-
 .../encoder/EncodableFacetUsingEncoderDecoder.java |   2 +-
 .../ignore/javalang/RemoveMethodsFacetFactory.java |  10 +-
 .../title/parser/TitleFacetUsingValueFacet.java    |   6 +-
 .../object/value/MaxLengthFacetUsingParser.java    |   2 +-
 .../value/TypicalLengthFacetUsingParser.java       |   2 +-
 .../metamodel/facets/object/value/ValueFacet.java  |  10 +-
 .../facets/object/value/ValueFacetAbstract.java    |  10 +-
 ...ionOrAnyMatchingValueSemanticsFacetFactory.java |   8 +-
 .../vsp/ValueFacetUsingSemanticsProvider.java      |   2 +-
 .../value/vsp/ValueSemanticsFacetAbstract.java     |   8 +-
 ...acetForPersistentBigDecimalWhenUnspecified.java |  45 ++-
 .../core/metamodel/inspect/model/ActionNode.svg    | 151 +++++-----
 .../metamodel/inspect/model/CollectionNode.svg     | 151 +++++-----
 .../core/metamodel/inspect/model/FacetAttrNode.svg | 156 +++++-----
 .../metamodel/inspect/model/FacetGroupNode.svg     | 151 +++++-----
 .../core/metamodel/inspect/model/FacetNode.svg     | 139 ++++-----
 .../core/metamodel/inspect/model/ParameterNode.svg | 151 +++++-----
 .../core/metamodel/inspect/model/PropertyNode.svg  | 158 +++++-----
 .../isis/core/metamodel/inspect/model/TypeNode.svg | 151 +++++-----
 .../isis/core/metamodel/inspect/model/icons.html   |  70 +++++
 .../interactions/managed/ManagedAction.java        |  15 +-
 .../managed/ParameterNegotiationModel.java         |   2 +-
 .../interactions/managed/_BindingUtil.java         |   4 +-
 .../identify/ObjectBookmarker_builtinHandlers.java |   2 +-
 .../memento/ObjectMemorizer_builtinHandlers.java   |   4 +-
 .../bootstrap3/GridSystemServiceBootstrap.java     |   8 +-
 .../core/metamodel/spec/ObjectSpecification.java   |   2 +-
 .../valuesemantics/BigDecimalValueSemantics.java   |  12 +-
 .../valuesemantics/BigIntegerValueSemantics.java   |  10 +-
 .../valuesemantics/BlobValueSemantics.java         |   8 +-
 ...eSemantics.java => BookmarkValueSemantics.java} |  50 ++--
 .../valuesemantics/BooleanValueSemantics.java      |  12 +-
 .../BufferedImageValueSemantics.java               |   4 +-
 .../valuesemantics/ByteValueSemantics.java         |  10 +-
 .../valuesemantics/ChangesDtoValueSemantics.java   |   6 +-
 .../valuesemantics/CharacterValueSemantics.java    |  10 +-
 .../valuesemantics/ClobValueSemantics.java         |   8 +-
 .../valuesemantics/CommandDtoValueSemantics.java   |   6 +-
 .../valuesemantics/DoubleValueSemantics.java       |  10 +-
 .../valuesemantics/EnumValueSemanticsAbstract.java |  12 +-
 .../valuesemantics/FloatValueSemantics.java        |  10 +-
 .../valuesemantics/IntValueSemantics.java          |  10 +-
 .../InteractionDtoValueSemantics.java              |   6 +-
 .../LocalResourcePathValueSemantics.java           |   8 +-
 .../valuesemantics/LongValueSemantics.java         |  10 +-
 .../valuesemantics/MarkupValueSemantics.java       |  10 +-
 ...lueSemantics.java => OidDtoValueSemantics.java} |  55 ++--
 .../valuesemantics/PasswordValueSemantics.java     |   8 +-
 .../valuesemantics/ShortValueSemantics.java        |  10 +-
 .../valuesemantics/StringValueSemantics.java       |   8 +-
 .../valuesemantics/TreeNodeValueSemantics.java     |   6 +-
 .../valuesemantics/URLValueSemantics.java          |  10 +-
 .../valuesemantics/UUIDValueSemantics.java         |  13 +-
 .../temporal/LocalDateTimeValueSemantics.java      |  35 +--
 .../temporal/LocalDateValueSemantics.java          |  27 +-
 .../temporal/LocalTimeValueSemantics.java          |  32 +-
 .../temporal/OffsetDateTimeValueSemantics.java     |  33 +--
 .../temporal/OffsetTimeValueSemantics.java         |  30 +-
 .../temporal/TemporalValueSemanticsProvider.java   | 161 ++++-------
 .../temporal/ZonedDateTimeValueSemantics.java      |  33 +--
 .../temporal/legacy/JavaSqlDateValueSemantics.java | 130 +--------
 .../legacy/JavaSqlTimeStampValueSemantics.java     | 110 +------
 .../temporal/legacy/JavaSqlTimeValueSemantics.java | 128 +-------
 .../legacy/JavaUtilDateValueSemantics.java         | 130 ++-------
 .../LegacyTemporalValueSemanticsAbstract.java      | 322 ---------------------
 .../legacy/joda/JodaDateTimeValueSemantics.java    | 182 ------------
 .../joda/JodaLocalDateTimeValueSemantics.java      | 230 ---------------
 .../legacy/joda/JodaLocalDateValueSemantics.java   | 232 ---------------
 .../temporal/legacy/joda/_JodaFunctions.java       |  42 ---
 .../legacy/joda/_JodaLocalDateTimeUtil.java        | 119 --------
 .../temporal/legacy/joda/_JodaLocalDateUtil.java   | 128 --------
 .../valuetypes/ValueSemanticsAdapter.java          | 110 +++++++
 .../valuetypes/ValueSemanticsRegistryDefault.java  |   2 +-
 .../object/mixin/MixinIntendedAsActionTest.java    |  67 +++--
 .../value/BooleanValueSemanticsProviderTest.java   |   2 +-
 .../JavaSqlDateValueSemanticsProviderTest.java     |  32 +-
 .../JavaSqlTimeValueSemanticsProviderTest.java     |  48 +--
 .../JavaUtilDateValueSemanticsProviderTest.java    |  68 ++---
 .../ValueSemanticsProviderAbstractTestCase.java    |   4 +-
 core/pom.xml                                       |  10 +-
 core/runtime/pom.xml                               |   6 +
 .../isis/core/runtime/IsisModuleCoreRuntime.java   |   4 +
 .../session/InteractionServiceDefault.java         |   5 +-
 .../wrapper/WrapperFactoryDefault.java             |  29 +-
 .../handlers/DomainObjectInvocationHandler.java    |   2 +-
 .../AsciiDocValueSemanticsWithPreprocessing.java   |   2 +-
 .../jdo/ComplexNumberJdoValueSemantics.java        |  12 +-
 .../jpa/ComplexNumberJpaValueSemantics.java        |  12 +-
 .../renderDay/PropertyLayoutRenderDayVm.java       |  15 +-
 .../jodatime/jodadatetime/vm/JodaDateTimeVm.java   |  11 +-
 .../jodatime/jodalocaldate/vm/JodaLocalDateVm.java |  11 +-
 .../jodalocaldatetime/vm/JodaLocalDateTimeVm.java  |  11 +-
 .../jodatime/jodalocaltime/vm/JodaLocalTimeVm.java |   9 +-
 .../common/ui/custom/WhereInTheWorldPanel.java     |   5 +-
 .../value/CalendarEventSemanticsProvider.java      |   8 +-
 .../ui/components/ScalarPanelAbstractLegacy.java   |   4 +-
 .../components/temporal/TemporalFieldFactory.java  |   6 +-
 .../components/temporal/TemporalFieldFactory.java  |   6 +-
 isis-parent/pom.xml                                |   2 +-
 regressiontests/pom.xml                            |   1 +
 .../DomainModelTest_usingGoodDomain.java           |   8 +
 .../testdomain/interact/ActionInteractionTest.java |  38 ++-
 regressiontests/stable-value/log4j2-test.xml       |  78 +++++
 .../stable-value}/pom.xml                          |  39 +--
 .../isis/testdomain/value/ValueSemanticsTest.java  | 183 ++++++++++++
 .../testdomain/value/ValueSemanticsTester.java     | 151 ++++++++++
 .../testdomain/viewers/InteractionTestWkt.java     |   3 +-
 .../testdomain/model/good/ProperGenericImpl.java   |  23 +-
 .../model/good/ProperGenericInterface.java         |  13 +-
 .../valuetypes/Configuration_usingValueTypes.java  |  23 +-
 .../model/valuetypes/ValueTypeExample.java         | 268 +++++++++++++++++
 .../model/valuetypes/ValueTypeExampleService.java  |  23 +-
 .../interaction/DomainObjectTesterFactory.java     |  20 ++
 starters/pom.xml                                   |   4 +-
 tooling/pom.xml                                    |   2 +-
 .../semantics/AsciiDocValueSemantics.java          |  10 +-
 .../semantics/XmlValueSemanticsAbstract.java       |   8 +-
 ...JaxbAdapters.java => JodaTimeJaxbAdapters.java} |   4 +-
 .../JodaTimeXMLGregorianCalendarMarshalling.java   |  20 +-
 valuetypes/jodatime/{ => integration}/pom.xml      |  35 ++-
 .../IsisModuleValJodatimeIntegration.java          |  32 +-
 .../valuesemantics/JodaDateTimeValueSemantics.java |  67 +++++
 .../JodaLocalDateTimeValueSemantics.java           |  65 +++++
 .../JodaLocalDateValueSemantics.java               |  65 +++++
 .../JodaLocalTimeValueSemantics.java               |   7 +-
 ...odaLocalDateTimeValueSemanticsProviderTest.java |  29 +-
 valuetypes/jodatime/pom.xml                        |   1 +
 .../semantics/MarkdownValueSemantics.java          |   8 +-
 valuetypes/pom.xml                                 |   7 +-
 .../viewer/common/model/object/ObjectUiModel.java  |  17 +-
 .../rendering/domainobjects/JsonValueEncoder.java  |   2 +-
 .../converter}/ConverterBasedOnValueSemantics.java |  44 ++-
 .../wicket/model/models/ChainingObjectModel.java   |   8 +-
 .../viewer/wicket/model/models/EntityModel.java    |  17 +-
 .../viewer/wicket/model/models/ScalarModel.java    |  16 +-
 .../wicket/model/models/ScalarParameterModel.java  |   2 +-
 .../wicket/model/models/ScalarPropertyModel.java   |   9 +-
 viewers/wicket/ui/pom.xml                          |   2 +-
 .../ui/app/registry/ComponentFactoryRegistry.java  |   6 +-
 .../ajaxtable/columns/GenericPropertyColumn.java   |   3 +-
 .../components/entity/fieldset/PropertyGroup.java  |   3 +-
 .../ui/components/property/PropertyEditPanel.java  |   3 +-
 .../components/scalars/DateConverterAbstract.java  |  76 -----
 .../ui/components/scalars/DateFormatSettings.java  |  86 ------
 .../ui/components/scalars/ScalarPanelAbstract.java |  13 +-
 .../scalars/ScalarPanelTextFieldAbstract.java      | 130 ++++-----
 .../ScalarPanelTextFieldDatePickerAbstract.java    | 116 --------
 ...va => ScalarPanelTextFieldNumericAbstract.java} |  18 +-
 .../ScalarPanelTextFieldParseableAbstract.java     |  68 -----
 ...va => ScalarPanelTextFieldTextualAbstract.java} |  45 ++-
 ...arPanelTextFieldWithTemporalPickerAbstract.java |  91 ++++++
 ...arPanelTextFieldWithValueSemanticsAbstract.java |  56 ++++
 ...ConverterPlugin.java => TemporalConverter.java} |  22 +-
 .../components/scalars/TextFieldStringModel.java   |  44 ---
 .../ui/components/scalars/TextFieldValueModel.java |   6 +-
 .../blobclob/IsisBlobOrClobPanelAbstract.java      |   6 -
 .../components/scalars/bookmark/BookmarkPanel.java |  15 +-
 .../datepicker/TextFieldWithDateTimePicker.java    |  54 ++--
 .../jdk8time/DateConverterForJdk8Abstract.java     |  64 ----
 .../jdk8time/DateConverterForJdk8LocalDate.java    |  66 -----
 .../DateConverterForJdk8LocalDateTime.java         |  77 -----
 .../DateConverterForJdk8OffsetDateTime.java        |  94 ------
 .../scalars/jdk8time/Jdk8LocalDatePanel.java       |  10 +-
 .../scalars/jdk8time/Jdk8LocalDateTimePanel.java   |  21 +-
 .../scalars/jdk8time/Jdk8OffsetDateTimePanel.java  |  20 +-
 .../jdkdates/DateConverterForJavaAbstract.java     | 105 -------
 .../jdkdates/DateConverterForJavaSqlDate.java      |  58 ----
 .../jdkdates/DateConverterForJavaSqlTimestamp.java |  60 ----
 .../jdkdates/DateConverterForJavaUtilDate.java     |  59 ----
 .../scalars/jdkdates/JavaSqlDatePanel.java         |  10 +-
 .../scalars/jdkdates/JavaSqlTimePanel.java         |  10 +-
 .../scalars/jdkdates/JavaSqlTimestampPanel.java    |  16 +-
 .../scalars/jdkdates/JavaUtilDatePanel.java        |  17 +-
 .../scalars/jdkmath/JavaMathBigDecimalPanel.java   |  28 +-
 .../scalars/jdkmath/JavaMathBigIntegerPanel.java   |  26 +-
 .../jodatime/DateConverterForJodaAbstract.java     |  57 ----
 .../jodatime/DateConverterForJodaDateTime.java     |  63 ----
 .../jodatime/DateConverterForJodaLocalDate.java    |  63 ----
 .../DateConverterForJodaLocalDateTime.java         |  64 ----
 .../scalars/jodatime/JodaDateTimePanel.java        |  19 +-
 .../scalars/jodatime/JodaLocalDatePanel.java       |  10 +-
 .../scalars/jodatime/JodaLocalDateTimePanel.java   |  20 +-
 .../scalars/jodatime/JodaLocalTimePanel.java       |  26 +-
 .../scalars/markup/ParentedMarkupPanel.java        |   5 -
 .../ui/components/scalars/oiddto/OidDtoPanel.java  |  16 +-
 .../scalars/oiddto/OidDtoPanelFactory.java         |   4 +-
 .../scalars/passwd/IsisPasswordPanel.java          |  20 +-
 .../components/scalars/primitive/BooleanPanel.java |   6 -
 .../ui/components/scalars/primitive/BytePanel.java |  24 +-
 .../scalars/primitive/CharacterPanel.java          |  11 +-
 .../components/scalars/primitive/DoublePanel.java  |  26 +-
 .../components/scalars/primitive/FloatPanel.java   |  25 +-
 .../components/scalars/primitive/IntegerPanel.java |  25 +-
 .../ui/components/scalars/primitive/LongPanel.java |  26 +-
 .../components/scalars/primitive/ShortPanel.java   |  25 +-
 .../scalars/reference/ReferencePanel.java          |  41 +--
 .../scalars/string/MultiLineStringPanel.java       |  15 +-
 .../ui/components/scalars/string/StringPanel.java  |  11 +-
 .../ui/components/scalars/uuid/UuidConverter.java  |  63 ----
 .../ui/components/scalars/uuid/UuidPanel.java      |  26 +-
 .../scalars/value/compound/ValueCompoundPanel.java |  13 +-
 .../scalars/value/fallback/ValueFallbackPanel.java |  11 +-
 .../valuechoices/ValueChoicesSelect2Panel.java     |   5 -
 .../{TreePanel.java => ParentedTreePanel.java}     |  15 +-
 .../ui/components/tree/TreePanelFactories.java     |   4 +-
 .../ui/components/unknown/UnknownModelPanel.java   |  12 +-
 .../entitysimplelink/EntityLinkSimplePanel.java    |   2 +-
 .../widgets/zclip/ZeroClipboardPanel.java          |   5 +-
 .../wicket/ui/panels/FormExecutorDefault.java      |  16 +-
 .../org/apache/isis/viewer/wicket/ui/util/Wkt.java |  60 +++-
 .../ui/components/scalars/ConverterTester.java     | 194 +++++++++++++
 .../jdkdates/DateConverterForJavaSqlDateTest.java  |  77 -----
 .../jdkdates/DateConverterForJavaUtilDateTest.java | 101 -------
 .../scalars/jdkdates/JavaSqlDateConverterTest.java |  75 +++++
 .../jdkdates/JavaUtilDateConverterTest.java        |  77 +++++
 .../scalars/jdkmath/BigDecimalConverterTest.java   | 140 +++++++++
 .../jdkmath/BigDecimalConverter_roundtrip.java     | 184 ------------
 .../jodatime/DateConverterForJodaDateTimeTest.java |  97 -------
 .../DateConverterForJodaLocalDateTest.java         |  73 -----
 .../DateConverterForJodaLocalDateTimeTest.java     |  96 ------
 .../jodatime/JodaDateTimeConverterTest.java        |  78 +++++
 .../jodatime/JodaLocalDateConverterTest.java       |  76 +++++
 .../jodatime/JodaLocalDateTimeConverterTest.java   |  77 +++++
 .../DateConverterForJdk8LocalDateTest.java         |  75 -----
 .../DateConverterForJdk8LocalDateTimeTest.java     |  98 -------
 .../DateConverterForJdk8OffsetDateTimeTest.java    | 108 -------
 .../jodatime/jdk8time/LocalDateConverterTest.java  |  74 +++++
 .../jdk8time/LocalDateTimeConverterTest.java       |  74 +++++
 .../jdk8time/OffsetDateTimeConverterTest.java      |  81 ++++++
 .../components/scalars/uuid/UuidConverterTest.java |  73 +++++
 .../scalars/uuid/UuidConverterTest_roundtrip.java  |  73 -----
 279 files changed, 4449 insertions(+), 6494 deletions(-)

[isis] 02/06: ISIS-2348 Add open to Command interface, amend LoginPrompt with nextCommand

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

joergrade pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit a2821bc8f348b9add3c227a3423891c8d931a404
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Wed Nov 17 17:49:14 2021 +0100

    ISIS-2348 Add open to Command interface, amend LoginPrompt with nextCommand
---
 .../isis/client/kroviz/core/event/ReplayCommand.kt   | 20 ++++++++++++--------
 .../apache/isis/client/kroviz/ui/core/RoMenuBar.kt   |  2 +-
 .../org/apache/isis/client/kroviz/ui/dialog/About.kt |  5 ++---
 .../isis/client/kroviz/ui/dialog/BrowserWindow.kt    |  2 +-
 .../apache/isis/client/kroviz/ui/dialog/Command.kt   |  4 ++++
 .../isis/client/kroviz/ui/dialog/DiagramDialog.kt    |  4 ++--
 .../isis/client/kroviz/ui/dialog/DownloadDialog.kt   |  2 +-
 .../isis/client/kroviz/ui/dialog/ErrorDialog.kt      |  2 +-
 .../isis/client/kroviz/ui/dialog/EventDialog.kt      |  4 ++--
 .../client/kroviz/ui/dialog/EventExportDialog.kt     |  2 +-
 .../client/kroviz/ui/dialog/EventImportDialog.kt     |  2 +-
 .../isis/client/kroviz/ui/dialog/EventLogDetail.kt   |  2 +-
 .../isis/client/kroviz/ui/dialog/FileDialog.kt       |  2 +-
 .../isis/client/kroviz/ui/dialog/LoginPrompt.kt      | 18 ++++++++++++------
 .../client/kroviz/ui/dialog/NotificationDialog.kt    |  2 +-
 .../apache/isis/client/kroviz/ui/dialog/SvgInline.kt |  2 +-
 .../isis/client/kroviz/ui/dialog/UndefinedDialog.kt  |  2 +-
 17 files changed, 45 insertions(+), 32 deletions(-)

diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ReplayCommand.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ReplayCommand.kt
index 04bf437..1a46437 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ReplayCommand.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ReplayCommand.kt
@@ -29,25 +29,29 @@ import org.apache.isis.client.kroviz.to.Represention
 import org.apache.isis.client.kroviz.to.TObject
 import org.apache.isis.client.kroviz.ui.core.Constants
 import org.apache.isis.client.kroviz.ui.core.UiManager
+import org.apache.isis.client.kroviz.ui.dialog.Command
 import org.apache.isis.client.kroviz.ui.dialog.ReplayDiffDialog
 
 val AppScope = CoroutineScope(window.asCoroutineDispatcher())
 
-class ReplayCommand {
+class ReplayCommand : Command() {
     private val eventStore = UiManager.getEventStore()
     private val oldBaseUrl = UiManager.getBaseUrl()
+    private var urlUnderTest: String = Constants.demoUrlRemote
+    private var userUnderTest: String = Constants.demoUser
+    private var passUnderTest: String = Constants.demoPass
 
-    fun execute(
-        urlUnderTest: String = Constants.demoUrlRemote,
-        userUnderTest: String = Constants.demoUser,
-        passUnderTest: String = Constants.demoPass
-    ) {
+    fun initUnderTest(url:String, user:String, pass:String) {
+        urlUnderTest = url
+        userUnderTest = user
+        passUnderTest = pass
+    }
+
+    override fun open() {
         val expectedEvents = copyEvents(eventStore.log)
         eventStore.reset()
         main() // re-creates the UI, but keeps the UiManager(singleton/object) and the session
         UiManager.login(urlUnderTest, userUnderTest, passUnderTest)
-        console.log("[RC.execute]")
-        console.log(urlUnderTest)
 
         val uiEvents = filterReplayEvents(expectedEvents)
         replay(uiEvents, urlUnderTest)
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 a6043b5..cb11e4d 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
@@ -121,7 +121,7 @@ class RoMenuBar : SimplePanel() {
 
         val aboutTitle = "About"
         mainMenu.add(
-            buildMenuEntry(aboutTitle, "Info", { UiManager.add(aboutTitle, About().open()) })
+            buildMenuEntry(aboutTitle, "Info", { UiManager.add(aboutTitle, About().dialog) })
         )
 
         return mainMenu
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/About.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/About.kt
index 216e3cf..2885f91 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/About.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/About.kt
@@ -25,13 +25,12 @@ import org.apache.isis.client.kroviz.ui.core.RoDialog
 import org.apache.isis.client.kroviz.utils.UUID
 
 class About : Command() {
-    private var dialog: RoDialog
+    var dialog: RoDialog
     private val formItems = mutableListOf<FormItem>()
     private val _LI = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
 
-    fun open() : RoDialog {
+    override fun open()  {
         dialog.open()
-        return dialog
     }
 
     init {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/BrowserWindow.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/BrowserWindow.kt
index cb17990..8910240 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/BrowserWindow.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/BrowserWindow.kt
@@ -24,7 +24,7 @@ import org.apache.isis.client.kroviz.ui.core.RoDialog
 
 class BrowserWindow(val url: String) : Command() {
 
-    fun open() {
+    override fun open() {
         val formItems = mutableListOf<FormItem>()
         formItems.add(FormItem("URL", ValueType.IFRAME, url))
         RoDialog(
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/Command.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/Command.kt
index dea42e8..0daaad9 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/Command.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/Command.kt
@@ -28,6 +28,10 @@ abstract class Command {
         // subclass responsibility
     }
 
+    open fun open() {
+        // subclass responsibility
+    }
+
     fun invoke(link: Link) {
         ResourceProxy().fetch(link, ActionDispatcher())
     }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DiagramDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DiagramDialog.kt
index 4c7bf1a..623994d 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DiagramDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DiagramDialog.kt
@@ -35,7 +35,7 @@ class DiagramDialog(
     private var dialog: RoDialog
     private val formItems = mutableListOf<FormItem>()
 
-    fun open() {
+    override fun open() {
         dialog.open()
         UmlUtils.generateJsonDiagram(pumlCode, callBack)
     }
@@ -81,7 +81,7 @@ class DiagramDialog(
         DomUtil.replaceWith(callBack as UUID, svg)
     }
 
-    fun buildMenu(): List<KvisionHtmlLink> {
+    private fun buildMenu(): List<KvisionHtmlLink> {
         val menu = mutableListOf<KvisionHtmlLink>()
         menu.add(buildPinAction())
         menu.add(buildDownloadAction())
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DownloadDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DownloadDialog.kt
index 75b689c..043fb92 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DownloadDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/DownloadDialog.kt
@@ -29,7 +29,7 @@ class DownloadDialog(val fileName:String, val content:String) : Command() {
     private lateinit var form: RoDialog
     val formItems = mutableListOf<FormItem>()
 
-    fun open() {
+    override fun open() {
         formItems.add(FormItem("Preview", ValueType.TEXT_AREA, content, 15))
         form = RoDialog(caption = "Download: $fileName", items = formItems, command = this)
         form.open()
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ErrorDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ErrorDialog.kt
index adf7658..0c6a77f 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ErrorDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/ErrorDialog.kt
@@ -26,7 +26,7 @@ import org.apache.isis.client.kroviz.ui.core.RoDialog
 
 class ErrorDialog(val logEntry: LogEntry) : Command() {
 
-    fun open() {
+    override fun open() {
         val error = logEntry.getTransferObject() as HttpErrorResponse
         val formItems = mutableListOf<FormItem>()
         formItems.add(FormItem("URL", ValueType.TEXT, logEntry.url))
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventDialog.kt
index 712c6fc..887d78c 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventDialog.kt
@@ -84,7 +84,7 @@ class EventDialog() : Command() {
                 dialog.close()
             }
             action == REP -> {
-                ReplayCommand().execute()
+                LoginPrompt(ReplayCommand()).open()
                 dialog.close()
             }
             else -> {
@@ -92,7 +92,7 @@ class EventDialog() : Command() {
         }
     }
 
-    fun open() {
+    override fun open() {
         dialog.open()
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventExportDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventExportDialog.kt
index 9f56227..365fdaf 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventExportDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventExportDialog.kt
@@ -120,7 +120,7 @@ class EventExportDialog() : Command() {
         }
     }
 
-    fun open() {
+    override fun open() {
         val format = mutableListOf<StringPair>()
         format.add(StringPair("CSV", "CSV"))
         format.add(StringPair("JSON", "JSON"))
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventImportDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventImportDialog.kt
index 52fe9a9..0ae1366 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventImportDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventImportDialog.kt
@@ -120,7 +120,7 @@ class EventImportDialog() : Command() {
         }
     }
 
-    fun open() {
+    override fun open() {
         val format = mutableListOf<StringPair>()
         format.add(StringPair("CSV", "CSV"))
         format.add(StringPair("JSON", "JSON"))
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt
index 1c5ed95..8002a38 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt
@@ -49,7 +49,7 @@ class EventLogDetail(val logEntryFromTabulator: LogEntry) : Command() {
     private val LNK: String = "lnk"
     private val DPM: String = "dpm"
 
-    fun open() {
+    override fun open() {
         val responseStr = if (logEntry.subType == Constants.subTypeJson) {
             StringUtils.format(logEntry.response)
         } else {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/FileDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/FileDialog.kt
index d566d3a..5f4bb3a 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/FileDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/FileDialog.kt
@@ -26,7 +26,7 @@ import org.apache.isis.client.kroviz.ui.core.RoDialog
 
 class FileDialog(val logEntry: LogEntry) : Command() {
 
-    fun open() {
+    override fun open() {
         val rv = logEntry.getTransferObject() as ResultValue
         val rvr = rv.result!!
         val value = rvr.value!!.content as String
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/LoginPrompt.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/LoginPrompt.kt
index 8a3b12f..b55e5f8 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/LoginPrompt.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/LoginPrompt.kt
@@ -22,6 +22,7 @@ import io.kvision.core.StringPair
 import io.kvision.form.select.SimpleSelect
 import io.kvision.form.text.Password
 import io.kvision.form.text.Text
+import org.apache.isis.client.kroviz.core.event.ReplayCommand
 import org.apache.isis.client.kroviz.to.Link
 import org.apache.isis.client.kroviz.to.ValueType
 import org.apache.isis.client.kroviz.ui.core.Constants
@@ -29,7 +30,7 @@ import org.apache.isis.client.kroviz.ui.core.FormItem
 import org.apache.isis.client.kroviz.ui.core.RoDialog
 import org.apache.isis.client.kroviz.ui.core.UiManager
 
-class LoginPrompt : Command() {
+class LoginPrompt(val nextCommand: Command? = null) : Command() {
 
     private lateinit var form: RoDialog
 
@@ -38,7 +39,7 @@ class LoginPrompt : Command() {
     private var username = Constants.demoUser
     private var password = Constants.demoPass
 
-    fun open() {
+    override fun open() {
         val formItems = mutableListOf<FormItem>()
         val urlList = mutableListOf<StringPair>()
         urlList.add(StringPair(Constants.demoUrl, Constants.demoUrl))
@@ -53,10 +54,15 @@ class LoginPrompt : Command() {
 
     override fun execute(action: String?) {
         extractUserInput()
-        UiManager.login(url, username, password)
-        val link = Link(href = url + Constants.restInfix)
-        invoke(link)
-        UiManager.closeDialog(form)
+        if (nextCommand is ReplayCommand) {
+            nextCommand.initUnderTest(url, username, password)
+            nextCommand.open()
+        } else {
+            UiManager.login(url, username, password)
+            val link = Link(href = url + Constants.restInfix)
+            invoke(link)
+            UiManager.closeDialog(form)
+        }
     }
 
     private fun extractUserInput() {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/NotificationDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/NotificationDialog.kt
index ab2d562..bde8185 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/NotificationDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/NotificationDialog.kt
@@ -26,7 +26,7 @@ import org.apache.isis.client.kroviz.ui.core.UiManager
 
 class NotificationDialog(val message: String) : Command() {
 
-    fun open() {
+    override fun open() {
         val formItems = mutableListOf<FormItem>()
         val fi = FormItem("Message", ValueType.TEXT_AREA, message, size = 5)
         fi.readOnly = true
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/SvgInline.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/SvgInline.kt
index 2aab0f5..1343af8 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/SvgInline.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/SvgInline.kt
@@ -32,7 +32,7 @@ class SvgInline : Command() {
     private var dialog: RoDialog
     private val formItems = mutableListOf<FormItem>()
 
-    fun open() {
+    override fun open() {
         dialog.open()
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/UndefinedDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/UndefinedDialog.kt
index d29c7ab..f362aa2 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/UndefinedDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/UndefinedDialog.kt
@@ -33,7 +33,7 @@ class UndefinedDialog(val logEntry: LogEntry) : Command() {
 4. Implement a Handler under main/kotlin/org.ro.handler
 5. Amend main/kotlin/org.ro.handler/ResponseHandler by this new Handler"""
 
-    fun open() {
+    override fun open() {
         val formItems = mutableListOf<FormItem>()
         formItems.add(FormItem("Instructions", ValueType.TEXT_AREA, instruction, size = 7))
         formItems.add(FormItem("URL", ValueType.TEXT, logEntry.url))