From 67a417389be370c8e44c4ff304fd5fb26260cf13 Mon Sep 17 00:00:00 2001 From: Katarzyna Streich Date: Fri, 19 May 2017 11:25:56 +0100 Subject: [PATCH] Add counting of different flows to the widget. Change widget styling, add some icons. --- .../client/jfx/model/StateMachineDataModel.kt | 31 ++++++++++-- .../main/kotlin/net/corda/explorer/Main.kt | 30 ------------ .../corda/explorer/model/CordaViewModel.kt | 3 +- .../net/corda/explorer/views/Dashboard.kt | 2 + .../explorer/views/StateMachineViewer.kt | 49 +++++++++++++++---- .../corda/explorer/views/TransactionViewer.kt | 6 ++- .../views/cordapps/cash/CashViewer.kt | 2 +- .../net/corda/explorer/css/corda.css | 29 ++++++++--- 8 files changed, 98 insertions(+), 54 deletions(-) diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/StateMachineDataModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/StateMachineDataModel.kt index f4acd3613a..24c9dd4c25 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/StateMachineDataModel.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/StateMachineDataModel.kt @@ -1,11 +1,13 @@ package net.corda.client.jfx.model +import javafx.beans.property.SimpleIntegerProperty import javafx.beans.property.SimpleObjectProperty import javafx.beans.value.ObservableValue import javafx.collections.FXCollections import net.corda.client.jfx.utils.LeftOuterJoinedMap import net.corda.client.jfx.utils.fold import net.corda.client.jfx.utils.getObservableValues +import net.corda.client.jfx.utils.lift import net.corda.client.jfx.utils.recordAsAssociation import net.corda.core.ErrorOr import net.corda.core.flows.FlowInitiator @@ -36,18 +38,35 @@ data class StateMachineData( val id: StateMachineRunId, val stateMachineName: String, val flowInitiator: FlowInitiator, - val addRmStatus: ObservableValue, - val stateMachineStatus: ObservableValue + val smmStatus: Pair, ObservableValue> ) +data class Counter( + var errored: SimpleIntegerProperty = SimpleIntegerProperty(0), + var success: SimpleIntegerProperty = SimpleIntegerProperty(0), + var progress: SimpleIntegerProperty = SimpleIntegerProperty(0) +) { + fun addSmm() { progress.value += 1 } + fun removeSmm(result: ErrorOr<*>) { + progress.value -= 1 + when (result.error) { + null -> success.value += 1 + else -> errored.value += 1 + } + } +} + class StateMachineDataModel { private val stateMachineUpdates by observable(NodeMonitorModel::stateMachineUpdates) private val progressTracking by observable(NodeMonitorModel::progressTracking) private val progressEvents = progressTracking.recordAsAssociation(ProgressTrackingEvent::stateMachineId) + val counter = Counter() + private val stateMachineStatus = stateMachineUpdates.fold(FXCollections.observableHashMap>()) { map, update -> when (update) { is StateMachineUpdate.Added -> { + counter.addSmm() val flowInitiator= update.stateMachineInfo.initiator val added: SimpleObjectProperty = SimpleObjectProperty(StateMachineStatus.Added(update.stateMachineInfo.flowLogicClassName, flowInitiator)) @@ -56,6 +75,7 @@ class StateMachineDataModel { is StateMachineUpdate.Removed -> { val added = map[update.id] added ?: throw Exception("State machine removed with unknown id ${update.id}") + counter.removeSmm(update.result) added.set(StateMachineStatus.Removed(update.result)) } } @@ -63,9 +83,12 @@ class StateMachineDataModel { private val stateMachineDataList = LeftOuterJoinedMap(stateMachineStatus, progressEvents) { id, status, progress -> val smStatus = status.value as StateMachineStatus.Added - StateMachineData(id, smStatus.stateMachineName, smStatus.flowInitiator, status, - EasyBind.map(progress) { ProgressStatus(it?.message) }) + StateMachineData(id, smStatus.stateMachineName, smStatus.flowInitiator, + Pair(status, EasyBind.map(progress) { ProgressStatus(it?.message) })) }.getObservableValues() val stateMachinesAll = stateMachineDataList + val error = counter.errored + val success = counter.success + val progress = counter.progress } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/Main.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/Main.kt index 68570609f3..5b7c2bd83f 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/Main.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/Main.kt @@ -11,46 +11,16 @@ import jfxtras.resources.JFXtrasFontRoboto import joptsimple.OptionParser import net.corda.client.jfx.model.Models import net.corda.client.jfx.model.observableValue -import net.corda.client.mock.EventGenerator -import net.corda.client.mock.Generator -import net.corda.client.mock.pickOne -import net.corda.contracts.asset.Cash -import net.corda.core.contracts.Amount -import net.corda.core.contracts.GBP -import net.corda.core.contracts.USD -import net.corda.core.failure -import net.corda.core.messaging.FlowHandle -import net.corda.core.node.services.ServiceInfo -import net.corda.core.node.services.ServiceType -import net.corda.core.serialization.OpaqueBytes -import net.corda.core.success -import net.corda.core.transactions.SignedTransaction -import net.corda.core.utilities.ALICE -import net.corda.core.utilities.BOB -import net.corda.core.utilities.DUMMY_NOTARY import net.corda.core.utilities.loggerFor import net.corda.explorer.model.CordaViewModel import net.corda.explorer.model.SettingsModel import net.corda.explorer.views.* import net.corda.explorer.views.cordapps.cash.CashViewer -import net.corda.flows.CashExitFlow -import net.corda.flows.CashFlowCommand -import net.corda.flows.CashIssueFlow -import net.corda.flows.CashPaymentFlow -import net.corda.flows.IssuerFlow.IssuanceRequester -import net.corda.node.driver.PortAllocation -import net.corda.node.driver.driver -import net.corda.node.services.startFlowPermission -import net.corda.node.services.transactions.SimpleNotaryService -import net.corda.nodeapi.User import org.apache.commons.lang.SystemUtils -import org.bouncycastle.asn1.x500.X500Name import org.controlsfx.dialog.ExceptionDialog import tornadofx.App import tornadofx.addStageIcon import tornadofx.find -import java.time.Instant -import java.util.* /** * Main class for Explorer, you will need Tornado FX to run the explorer. diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/model/CordaViewModel.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/model/CordaViewModel.kt index 5967d955bf..cd7d6c2ffb 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/model/CordaViewModel.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/model/CordaViewModel.kt @@ -4,6 +4,7 @@ import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon import javafx.beans.property.SimpleObjectProperty import javafx.collections.ObservableList import javafx.scene.Node +import javafx.scene.control.Label import tornadofx.* class CordaViewModel { @@ -31,4 +32,4 @@ abstract class CordaView(title: String? = null) : View(title) { } } -data class CordaWidget(val name: String, val node: Node) \ No newline at end of file +data class CordaWidget(val name: String, val node: Node, val icon: FontAwesomeIcon? = null) \ No newline at end of file diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Dashboard.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Dashboard.kt index c5fc9ce711..7079a9ad3a 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Dashboard.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Dashboard.kt @@ -1,6 +1,7 @@ package net.corda.explorer.views import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon +import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView import javafx.beans.binding.Bindings import javafx.collections.ObservableList import javafx.scene.Node @@ -46,6 +47,7 @@ class Dashboard : CordaView() { selectedView.value = view } } + it.icon?.let { graphic = FontAwesomeIconView(it).apply { glyphSize = 30.0 } } } } } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/StateMachineViewer.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/StateMachineViewer.kt index d31ac1cfa3..d583f54bf6 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/StateMachineViewer.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/StateMachineViewer.kt @@ -5,10 +5,11 @@ import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView import javafx.beans.binding.Bindings import javafx.collections.ObservableList import javafx.geometry.HPos -import javafx.geometry.Pos +import javafx.geometry.Insets import javafx.scene.Parent import javafx.scene.control.Label import javafx.scene.control.TableView +import javafx.scene.input.MouseButton import javafx.scene.layout.BorderPane import javafx.scene.layout.GridPane import javafx.scene.layout.VBox @@ -18,7 +19,8 @@ import net.corda.client.jfx.model.StateMachineData import net.corda.client.jfx.model.StateMachineDataModel import net.corda.client.jfx.model.StateMachineStatus import net.corda.client.jfx.model.observableList -import net.corda.client.jfx.model.observableListReadOnly +import net.corda.client.jfx.model.observableValue +import net.corda.client.jfx.model.writableValue import net.corda.client.jfx.utils.map import net.corda.core.crypto.SecureHash import net.corda.core.crypto.toBase58String @@ -26,33 +28,60 @@ import net.corda.core.flows.FlowInitiator import net.corda.core.transactions.SignedTransaction import net.corda.explorer.formatters.FlowInitiatorFormatter import net.corda.explorer.formatters.FlowNameFormatter +import net.corda.explorer.formatters.PartyNameFormatter import net.corda.explorer.identicon.identicon import net.corda.explorer.identicon.identiconToolTip import net.corda.explorer.model.CordaView +import net.corda.explorer.model.CordaViewModel import net.corda.explorer.model.CordaWidget import net.corda.explorer.ui.setCustomCellFactory import tornadofx.* + // TODO Rethink whole idea of showing communication as table, it should be tree view for each StateMachine (with subflows). class StateMachineViewer : CordaView("Flow Triage") { override val root by fxml() override val icon = FontAwesomeIcon.HEARTBEAT - override val widgets = listOf(CordaWidget(title, StateMachineViewer.StateMachineWidget())).observable() + override val widgets = listOf(CordaWidget(title, StateMachineWidget(), icon)).observable() private val allViewTable by fxid>() private val matchingFlowsLabel by fxid