mirror of
https://github.com/corda/corda.git
synced 2025-01-30 08:04:16 +00:00
explorer: Add input/output states and signers to tx screen
This commit is contained in:
parent
db9eb060b9
commit
26aed70e24
@ -1,7 +1,7 @@
|
||||
package com.r3corda.client.model
|
||||
|
||||
import com.r3corda.client.fxutils.foldToObservableList
|
||||
import com.r3corda.core.transactions.SignedTransaction
|
||||
import com.r3corda.core.transactions.LedgerTransaction
|
||||
import com.r3corda.node.services.monitor.ServiceToClientEvent
|
||||
import com.r3corda.node.services.monitor.TransactionBuildResult
|
||||
import com.r3corda.node.utilities.AddOrRemove
|
||||
@ -18,7 +18,7 @@ interface GatheredTransactionData {
|
||||
val uuid: ObservableValue<UUID?>
|
||||
val protocolName: ObservableValue<String?>
|
||||
val protocolStatus: ObservableValue<ProtocolStatus?>
|
||||
val transaction: ObservableValue<SignedTransaction?>
|
||||
val transaction: ObservableValue<LedgerTransaction?>
|
||||
val status: ObservableValue<TransactionCreateStatus?>
|
||||
val lastUpdate: ObservableValue<Instant>
|
||||
val allEvents: ObservableList<out ServiceToClientEvent>
|
||||
@ -42,7 +42,7 @@ data class GatheredTransactionDataWritable(
|
||||
override val uuid: SimpleObjectProperty<UUID?> = SimpleObjectProperty(null),
|
||||
override val protocolName: SimpleObjectProperty<String?> = SimpleObjectProperty(null),
|
||||
override val protocolStatus: SimpleObjectProperty<ProtocolStatus?> = SimpleObjectProperty(null),
|
||||
override val transaction: SimpleObjectProperty<SignedTransaction?> = SimpleObjectProperty(null),
|
||||
override val transaction: SimpleObjectProperty<LedgerTransaction?> = SimpleObjectProperty(null),
|
||||
override val status: SimpleObjectProperty<TransactionCreateStatus?> = SimpleObjectProperty(null),
|
||||
override val lastUpdate: SimpleObjectProperty<Instant>,
|
||||
override val allEvents: ObservableList<ServiceToClientEvent> = FXCollections.observableArrayList()
|
||||
|
26
explorer/src/main/kotlin/com/r3corda/explorer/AmountDiff.kt
Normal file
26
explorer/src/main/kotlin/com/r3corda/explorer/AmountDiff.kt
Normal file
@ -0,0 +1,26 @@
|
||||
package com.r3corda.explorer
|
||||
|
||||
import com.r3corda.core.contracts.Amount
|
||||
|
||||
enum class Positivity {
|
||||
Positive,
|
||||
Negative
|
||||
}
|
||||
|
||||
val Positivity.sign: String get() = when (this) {
|
||||
Positivity.Positive -> ""
|
||||
Positivity.Negative -> "-"
|
||||
}
|
||||
|
||||
data class AmountDiff<T>(
|
||||
val positivity: Positivity,
|
||||
val amount: Amount<T>
|
||||
) {
|
||||
companion object {
|
||||
fun <T> fromLong(quantity: Long, token: T) =
|
||||
AmountDiff(
|
||||
positivity = if (quantity < 0) Positivity.Negative else Positivity.Positive,
|
||||
amount = Amount(Math.abs(quantity), token)
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.r3corda.explorer.ui
|
||||
|
||||
import com.r3corda.explorer.formatters.Formatter
|
||||
import javafx.scene.control.ListCell
|
||||
import javafx.scene.control.ListView
|
||||
import javafx.util.Callback
|
||||
|
||||
fun <T> Formatter<T>.toListCellFactory() = Callback<ListView<T?>, ListCell<T?>> {
|
||||
object : ListCell<T?>() {
|
||||
override fun updateItem(value: T?, empty: Boolean) {
|
||||
super.updateItem(value, empty)
|
||||
text = if (value == null || empty) {
|
||||
""
|
||||
} else {
|
||||
format(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,12 +7,18 @@ import com.r3corda.core.contracts.Amount
|
||||
import com.r3corda.core.contracts.CommandData
|
||||
import com.r3corda.core.contracts.withoutIssuer
|
||||
import com.r3corda.core.transactions.SignedTransaction
|
||||
import com.r3corda.core.contracts.*
|
||||
import com.r3corda.core.crypto.Party
|
||||
import com.r3corda.core.crypto.toStringShort
|
||||
import com.r3corda.core.transactions.LedgerTransaction
|
||||
import com.r3corda.explorer.AmountDiff
|
||||
import com.r3corda.explorer.formatters.AmountFormatter
|
||||
import com.r3corda.explorer.formatters.Formatter
|
||||
import com.r3corda.explorer.formatters.NumberFormatter
|
||||
import com.r3corda.explorer.model.IdentityModel
|
||||
import com.r3corda.explorer.model.ReportingCurrencyModel
|
||||
import com.r3corda.explorer.ui.SingleRowSelection
|
||||
import com.r3corda.explorer.ui.setColumnPrefWidthPolicy
|
||||
import com.r3corda.explorer.ui.singleRowSelection
|
||||
import com.r3corda.explorer.ui.toTableCellFactory
|
||||
import com.r3corda.explorer.sign
|
||||
import com.r3corda.explorer.ui.*
|
||||
import com.r3corda.node.services.monitor.ServiceToClientEvent
|
||||
import javafx.beans.binding.Bindings
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper
|
||||
@ -20,10 +26,8 @@ import javafx.beans.value.ObservableValue
|
||||
import javafx.collections.FXCollections
|
||||
import javafx.collections.ObservableList
|
||||
import javafx.geometry.Insets
|
||||
import javafx.scene.control.Label
|
||||
import javafx.scene.control.TableCell
|
||||
import javafx.scene.control.TableColumn
|
||||
import javafx.scene.control.TableView
|
||||
import javafx.scene.Node
|
||||
import javafx.scene.control.*
|
||||
import javafx.scene.layout.Background
|
||||
import javafx.scene.layout.BackgroundFill
|
||||
import javafx.scene.layout.CornerRadii
|
||||
@ -31,12 +35,15 @@ import javafx.scene.layout.VBox
|
||||
import javafx.scene.paint.Color
|
||||
import org.fxmisc.easybind.EasyBind
|
||||
import tornadofx.View
|
||||
import java.security.PublicKey
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
class TransactionViewer: View() {
|
||||
override val root: VBox by fxml()
|
||||
|
||||
val topSplitPane: SplitPane by fxid("TopSplitPane")
|
||||
|
||||
// Top half (transactions table)
|
||||
private val transactionViewTable: TableView<ViewerNode> by fxid("TransactionViewTable")
|
||||
private val transactionViewTransactionId: TableColumn<ViewerNode, String> by fxid("TransactionViewTransactionId")
|
||||
@ -44,9 +51,31 @@ class TransactionViewer: View() {
|
||||
private val transactionViewTransactionStatus: TableColumn<ViewerNode, Pair<TransactionCreateStatus?, ProtocolStatus?>> by fxid("TransactionViewTransactionStatus")
|
||||
private val transactionViewStatusUpdated: TableColumn<ViewerNode, Instant> by fxid("TransactionViewStatusUpdated")
|
||||
private val transactionViewCommandTypes: TableColumn<ViewerNode, String> by fxid("TransactionViewCommandTypes")
|
||||
private val transactionViewTotalValueEquiv: TableColumn<ViewerNode, Amount<Currency>> by fxid("TransactionViewTotalValueEquiv")
|
||||
private val transactionViewTotalValueEquiv: TableColumn<ViewerNode, AmountDiff<Currency>> by fxid("TransactionViewTotalValueEquiv")
|
||||
|
||||
// Bottom half (details)
|
||||
private val contractStatesTitledPane: TitledPane by fxid("ContractStatesTitledPane")
|
||||
|
||||
private val contractStatesInputStatesTable: TableView<StateNode> by fxid("ContractStatesInputStatesTable")
|
||||
private val contractStatesInputStatesId: TableColumn<StateNode, String> by fxid("ContractStatesInputStatesId")
|
||||
private val contractStatesInputStatesType: TableColumn<StateNode, Class<out ContractState>> by fxid("ContractStatesInputStatesType")
|
||||
private val contractStatesInputStatesOwner: TableColumn<StateNode, String> by fxid("ContractStatesInputStatesOwner")
|
||||
private val contractStatesInputStatesLocalCurrency: TableColumn<StateNode, Currency?> by fxid("ContractStatesInputStatesLocalCurrency")
|
||||
private val contractStatesInputStatesAmount: TableColumn<StateNode, Long> by fxid("ContractStatesInputStatesAmount")
|
||||
private val contractStatesInputStatesEquiv: TableColumn<StateNode, Amount<Currency>> by fxid("ContractStatesInputStatesEquiv")
|
||||
|
||||
private val contractStatesOutputStatesTable: TableView<StateNode> by fxid("ContractStatesOutputStatesTable")
|
||||
private val contractStatesOutputStatesId: TableColumn<StateNode, String> by fxid("ContractStatesOutputStatesId")
|
||||
private val contractStatesOutputStatesType: TableColumn<StateNode, Class<out ContractState>> by fxid("ContractStatesOutputStatesType")
|
||||
private val contractStatesOutputStatesOwner: TableColumn<StateNode, String> by fxid("ContractStatesOutputStatesOwner")
|
||||
private val contractStatesOutputStatesLocalCurrency: TableColumn<StateNode, Currency?> by fxid("ContractStatesOutputStatesLocalCurrency")
|
||||
private val contractStatesOutputStatesAmount: TableColumn<StateNode, Long> by fxid("ContractStatesOutputStatesAmount")
|
||||
private val contractStatesOutputStatesEquiv: TableColumn<StateNode, Amount<Currency>> by fxid("ContractStatesOutputStatesEquiv")
|
||||
|
||||
private val signaturesTitledPane: TitledPane by fxid("SignaturesTitledPane")
|
||||
private val signaturesList: ListView<PublicKey> by fxid("SignaturesList")
|
||||
|
||||
private val lowLevelEventsTitledPane: TitledPane by fxid("LowLevelEventsTitledPane")
|
||||
private val lowLevelEventsTable: TableView<ServiceToClientEvent> by fxid("LowLevelEventsTable")
|
||||
private val lowLevelEventsTimestamp: TableColumn<ServiceToClientEvent, Instant> by fxid("LowLevelEventsTimestamp")
|
||||
private val lowLevelEventsEvent: TableColumn<ServiceToClientEvent, ServiceToClientEvent> by fxid("LowLevelEventsEvent")
|
||||
@ -56,17 +85,24 @@ class TransactionViewer: View() {
|
||||
private val reportingExchange: ObservableValue<Pair<Currency, (Amount<Currency>) -> Amount<Currency>>>
|
||||
by observableValue(ReportingCurrencyModel::reportingExchange)
|
||||
|
||||
private val myIdentity: ObservableValue<Party> by observableValue(IdentityModel::myIdentity)
|
||||
|
||||
data class ViewerNode(
|
||||
val transactionId: ObservableValue<Pair<Long?, UUID?>>,
|
||||
val originator: ObservableValue<String>,
|
||||
val transactionStatus: ObservableValue<Pair<TransactionCreateStatus?, ProtocolStatus?>>,
|
||||
val statusUpdated: ObservableValue<Instant>,
|
||||
val commandTypes: ObservableValue<Collection<Class<CommandData>>>,
|
||||
val viewTotalValueEquiv: ObservableValue<Amount<Currency>?>,
|
||||
val transaction: ObservableValue<SignedTransaction?>,
|
||||
val totalValueEquiv: ObservableValue<AmountDiff<Currency>?>,
|
||||
val transaction: ObservableValue<LedgerTransaction?>,
|
||||
val allEvents: ObservableList<out ServiceToClientEvent>
|
||||
)
|
||||
|
||||
data class StateNode(
|
||||
val transactionState: TransactionState<*>,
|
||||
val stateRef: StateRef
|
||||
)
|
||||
|
||||
private val viewerNodes = EasyBind.map(gatheredTransactionDataList) {
|
||||
ViewerNode(
|
||||
transactionId = EasyBind.combine(it.fiberId, it.uuid) { fiberId, uuid -> Pair(fiberId, uuid) },
|
||||
@ -83,13 +119,13 @@ class TransactionViewer: View() {
|
||||
statusUpdated = it.lastUpdate,
|
||||
commandTypes = EasyBind.map(it.transaction) {
|
||||
val commands = mutableSetOf<Class<CommandData>>()
|
||||
it?.tx?.commands?.forEach {
|
||||
it?.commands?.forEach {
|
||||
commands.add(it.value.javaClass)
|
||||
}
|
||||
commands
|
||||
},
|
||||
viewTotalValueEquiv = EasyBind.combine(reportingExchange, it.transaction) { exchange, transaction ->
|
||||
transaction?.let { calculateTotalEquiv(exchange.first, exchange.second, transaction) }
|
||||
totalValueEquiv = EasyBind.combine(myIdentity, reportingExchange, it.transaction) { identity, exchange, transaction ->
|
||||
transaction?.let { calculateTotalEquiv(setOf(identity.owningKey), exchange.first, exchange.second, transaction) }
|
||||
},
|
||||
transaction = it.transaction,
|
||||
allEvents = it.allEvents
|
||||
@ -97,16 +133,60 @@ class TransactionViewer: View() {
|
||||
}
|
||||
|
||||
private fun calculateTotalEquiv(
|
||||
relevantPublicKeys: Set<PublicKey>,
|
||||
reportingCurrency: Currency,
|
||||
exchange: (Amount<Currency>) -> Amount<Currency>,
|
||||
transaction: SignedTransaction): Amount<Currency> {
|
||||
return transaction.tx.outputs.map { it.data }.filterIsInstance<Cash.State>().fold(
|
||||
initial = Amount(0, reportingCurrency),
|
||||
operation = { sum, cashState -> sum + exchange(cashState.amount.withoutIssuer()) }
|
||||
)
|
||||
transaction: LedgerTransaction): AmountDiff<Currency> {
|
||||
var sum = 0L
|
||||
transaction.inputs.forEach {
|
||||
val contractState = it.state.data
|
||||
if (contractState is Cash.State && relevantPublicKeys.contains(contractState.owner)) {
|
||||
sum -= exchange(contractState.amount.withoutIssuer()).quantity
|
||||
}
|
||||
}
|
||||
transaction.outputs.forEach {
|
||||
val contractState = it.data
|
||||
if (contractState is Cash.State && relevantPublicKeys.contains(contractState.owner)) {
|
||||
sum += exchange(contractState.amount.withoutIssuer()).quantity
|
||||
}
|
||||
}
|
||||
return AmountDiff.fromLong(sum, reportingCurrency)
|
||||
}
|
||||
|
||||
private val selectedViewerNode = transactionViewTable.singleRowSelection()
|
||||
private val selectedTransaction = EasyBind.monadic(selectedViewerNode).flatMap<LedgerTransaction?, SingleRowSelection<ViewerNode>> {
|
||||
when (it) {
|
||||
is SingleRowSelection.None -> ReadOnlyObjectWrapper(null)
|
||||
is SingleRowSelection.Selected -> it.node.transaction
|
||||
}
|
||||
}
|
||||
|
||||
private val inputStateNodes = ChosenList<StateNode>(EasyBind.map(selectedTransaction) {
|
||||
if (it == null) {
|
||||
FXCollections.emptyObservableList<StateNode>()
|
||||
} else {
|
||||
FXCollections.observableArrayList(it.inputs.map { StateNode(it.state, it.ref) })
|
||||
}
|
||||
})
|
||||
|
||||
private val outputStateNodes = ChosenList<StateNode>(EasyBind.map(selectedTransaction) {
|
||||
if (it == null) {
|
||||
FXCollections.emptyObservableList<StateNode>()
|
||||
} else {
|
||||
FXCollections.observableArrayList(it.outputs.mapIndexed { index, transactionState ->
|
||||
StateNode(transactionState, StateRef(it.id, index))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
private val signatures = ChosenList<PublicKey>(EasyBind.map(selectedTransaction) {
|
||||
if (it == null) {
|
||||
FXCollections.emptyObservableList<PublicKey>()
|
||||
} else {
|
||||
FXCollections.observableArrayList(it.mustSign)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
private val noLowLevelEvents = FXCollections.emptyObservableList<ServiceToClientEvent>()
|
||||
private val lowLevelEvents = ChosenList(EasyBind.map(selectedViewerNode) {
|
||||
@ -116,7 +196,78 @@ class TransactionViewer: View() {
|
||||
}
|
||||
})
|
||||
|
||||
private val allNodesShown = FXCollections.observableArrayList<Node>(
|
||||
transactionViewTable,
|
||||
contractStatesTitledPane,
|
||||
signaturesTitledPane,
|
||||
lowLevelEventsTitledPane
|
||||
)
|
||||
private val onlyTransactionsTableShown = FXCollections.observableArrayList<Node>(
|
||||
transactionViewTable
|
||||
)
|
||||
private val topSplitPaneNodesShown = ChosenList<Node>(
|
||||
EasyBind.map(selectedViewerNode) { selection ->
|
||||
if (selection is SingleRowSelection.None<*>) {
|
||||
onlyTransactionsTableShown
|
||||
} else {
|
||||
allNodesShown
|
||||
}
|
||||
})
|
||||
|
||||
private fun wireUpStatesTable(
|
||||
states: ObservableList<StateNode>,
|
||||
statesTable: TableView<StateNode>,
|
||||
statesId: TableColumn<StateNode, String>,
|
||||
statesType: TableColumn<StateNode, Class<out ContractState>>,
|
||||
statesOwner: TableColumn<StateNode, String>,
|
||||
statesLocalCurrency: TableColumn<StateNode, Currency?>,
|
||||
statesAmount: TableColumn<StateNode, Long>,
|
||||
statesEquiv: TableColumn<StateNode, Amount<Currency>>
|
||||
) {
|
||||
Bindings.bindContent(statesTable.items, states)
|
||||
|
||||
statesId.setCellValueFactory { ReadOnlyObjectWrapper(it.value.stateRef.toString()) }
|
||||
statesType.setCellValueFactory { ReadOnlyObjectWrapper(it.value.transactionState.data.javaClass) }
|
||||
statesOwner.setCellValueFactory {
|
||||
val state = it.value.transactionState.data
|
||||
if (state is OwnableState) {
|
||||
ReadOnlyObjectWrapper(state.owner.toStringShort())
|
||||
} else {
|
||||
ReadOnlyObjectWrapper("???")
|
||||
}
|
||||
}
|
||||
statesLocalCurrency.setCellValueFactory {
|
||||
val state = it.value.transactionState.data
|
||||
if (state is Cash.State) {
|
||||
ReadOnlyObjectWrapper(state.amount.token.product)
|
||||
} else {
|
||||
ReadOnlyObjectWrapper(null)
|
||||
}
|
||||
}
|
||||
statesAmount.setCellValueFactory {
|
||||
val state = it.value.transactionState.data
|
||||
if (state is Cash.State) {
|
||||
ReadOnlyObjectWrapper(state.amount.quantity)
|
||||
} else {
|
||||
ReadOnlyObjectWrapper(null)
|
||||
}
|
||||
}
|
||||
statesAmount.setCellFactory(NumberFormatter.longComma.toTableCellFactory())
|
||||
statesEquiv.setCellValueFactory {
|
||||
val state = it.value.transactionState.data
|
||||
if (state is Cash.State) {
|
||||
EasyBind.map(reportingExchange) { exchange ->
|
||||
exchange.second(state.amount.withoutIssuer())
|
||||
}
|
||||
} else {
|
||||
ReadOnlyObjectWrapper(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
Bindings.bindContent(topSplitPane.items, topSplitPaneNodesShown)
|
||||
|
||||
// Transaction table
|
||||
Bindings.bindContent(transactionViewTable.items, viewerNodes)
|
||||
|
||||
@ -155,7 +306,7 @@ class TransactionViewer: View() {
|
||||
null -> BackgroundFill(Color.TRANSPARENT, CornerRadii.EMPTY, Insets.EMPTY)
|
||||
}
|
||||
label.background = Background(backgroundFill)
|
||||
label.text = if (value.first == null && value.second == null){
|
||||
label.text = if (value.first == null && value.second == null) {
|
||||
"???"
|
||||
} else {
|
||||
(value.first?.toString() ?: "") + (value.second?.let { "[${it.toString()}]" } ?: "")
|
||||
@ -169,8 +320,39 @@ class TransactionViewer: View() {
|
||||
transactionViewCommandTypes.setCellValueFactory {
|
||||
EasyBind.map(it.value.commandTypes) { it.map { it.simpleName }.joinToString(",") }
|
||||
}
|
||||
transactionViewTotalValueEquiv.setCellValueFactory<ViewerNode, Amount<Currency>> { it.value.viewTotalValueEquiv }
|
||||
transactionViewTotalValueEquiv.cellFactory = AmountFormatter.comma.toTableCellFactory()
|
||||
transactionViewTotalValueEquiv.setCellValueFactory<ViewerNode, AmountDiff<Currency>> { it.value.totalValueEquiv }
|
||||
transactionViewTotalValueEquiv.cellFactory = object : Formatter<AmountDiff<Currency>> {
|
||||
override fun format(value: AmountDiff<Currency>) =
|
||||
"${value.positivity.sign}${AmountFormatter.comma.format(value.amount)}"
|
||||
}.toTableCellFactory()
|
||||
|
||||
// Contract states
|
||||
wireUpStatesTable(
|
||||
inputStateNodes,
|
||||
contractStatesInputStatesTable,
|
||||
contractStatesInputStatesId,
|
||||
contractStatesInputStatesType,
|
||||
contractStatesInputStatesOwner,
|
||||
contractStatesInputStatesLocalCurrency,
|
||||
contractStatesInputStatesAmount,
|
||||
contractStatesInputStatesEquiv
|
||||
)
|
||||
wireUpStatesTable(
|
||||
outputStateNodes,
|
||||
contractStatesOutputStatesTable,
|
||||
contractStatesOutputStatesId,
|
||||
contractStatesOutputStatesType,
|
||||
contractStatesOutputStatesOwner,
|
||||
contractStatesOutputStatesLocalCurrency,
|
||||
contractStatesOutputStatesAmount,
|
||||
contractStatesOutputStatesEquiv
|
||||
)
|
||||
|
||||
// Signatures
|
||||
Bindings.bindContent(signaturesList.items, signatures)
|
||||
signaturesList.cellFactory = object : Formatter<PublicKey> {
|
||||
override fun format(value: PublicKey) = value.toStringShort()
|
||||
}.toListCellFactory()
|
||||
|
||||
// Low level events
|
||||
Bindings.bindContent(lowLevelEventsTable.items, lowLevelEvents)
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
<?import java.lang.String?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Accordion?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.control.SplitPane?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
@ -11,7 +11,6 @@
|
||||
<?import javafx.scene.control.TitledPane?>
|
||||
<?import javafx.scene.image.Image?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
@ -40,7 +39,7 @@
|
||||
</ImageView>
|
||||
</children>
|
||||
</StackPane>
|
||||
<SplitPane dividerPositions="0.5" orientation="VERTICAL" prefHeight="562.0" prefWidth="1087.0" VBox.vgrow="ALWAYS">
|
||||
<SplitPane fx:id="TopSplitPane" dividerPositions="0.5, 0.5, 0.5" orientation="VERTICAL" prefHeight="562.0" prefWidth="1087.0" VBox.vgrow="ALWAYS">
|
||||
<items>
|
||||
<TableView fx:id="TransactionViewTable" prefHeight="200.0" prefWidth="200.0">
|
||||
<columns>
|
||||
@ -55,119 +54,86 @@
|
||||
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
|
||||
</columnResizePolicy>
|
||||
</TableView>
|
||||
<Accordion>
|
||||
<panes>
|
||||
<TitledPane text="Transaction details">
|
||||
<content>
|
||||
<AnchorPane>
|
||||
<TitledPane fx:id="ContractStatesTitledPane" animated="false" text="Contract states">
|
||||
<content>
|
||||
<SplitPane dividerPositions="0.5" prefHeight="160.0" prefWidth="200.0">
|
||||
<items>
|
||||
<VBox prefHeight="200.0" prefWidth="100.0">
|
||||
<children>
|
||||
<Label layoutX="5.0" layoutY="5.0" text="Transaction ID" />
|
||||
<Label layoutX="97.0" layoutY="5.0" text="IC-3902-29090-32091" AnchorPane.leftAnchor="95.0" AnchorPane.rightAnchor="15.0" />
|
||||
<Label layoutX="5.0" layoutY="33.0" text="Originator" />
|
||||
<Label layoutX="97.0" layoutY="33.0" prefHeight="16.0" text="C03102 HSBC GROUP PLC" AnchorPane.leftAnchor="95.0" AnchorPane.rightAnchor="15.0" />
|
||||
<Label layoutX="5.0" layoutY="49.0" prefHeight="26.0" prefWidth="78.0" text="Date/time originated" wrapText="true" />
|
||||
<Label layoutX="97.0" layoutY="49.0" text="2019-05-24 11:47 UTC" AnchorPane.leftAnchor="95.0" AnchorPane.rightAnchor="15.0" />
|
||||
<Label layoutX="5.0" layoutY="90.0" text="Current status" />
|
||||
<Label layoutX="104.0" layoutY="90.0" prefHeight="16.0" text="01800 - EXCEPTION - UNSPECIFIED NETWORK ERROR" AnchorPane.leftAnchor="95.0" AnchorPane.rightAnchor="15.0" />
|
||||
<Label text="Inputs: 23">
|
||||
<padding>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<TableView fx:id="ContractStatesInputStatesTable" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
|
||||
<columns>
|
||||
<TableColumn fx:id="ContractStatesInputStatesId" prefWidth="75.0" text="ID" />
|
||||
<TableColumn fx:id="ContractStatesInputStatesType" prefWidth="75.0" text="Type" />
|
||||
<TableColumn fx:id="ContractStatesInputStatesOwner" prefWidth="75.0" text="Owner" />
|
||||
<TableColumn fx:id="ContractStatesInputStatesLocalCurrency" prefWidth="75.0" styleClass="first-column" text="Local Ccy" />
|
||||
<TableColumn fx:id="ContractStatesInputStatesAmount" prefWidth="75.0" text="Amount">
|
||||
<styleClass>
|
||||
<String fx:value="second-column" />
|
||||
<String fx:value="monetary-value" />
|
||||
</styleClass>
|
||||
</TableColumn>
|
||||
<TableColumn fx:id="ContractStatesInputStatesEquiv" prefWidth="75.0" text="USD Equiv" />
|
||||
</columns>
|
||||
<columnResizePolicy>
|
||||
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
|
||||
</columnResizePolicy>
|
||||
</TableView>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</content></TitledPane>
|
||||
<TitledPane text="Contract states">
|
||||
<content>
|
||||
<SplitPane dividerPositions="0.5" prefHeight="160.0" prefWidth="200.0">
|
||||
<items>
|
||||
<VBox prefHeight="200.0" prefWidth="100.0">
|
||||
<children>
|
||||
<Label text="Inputs: 23">
|
||||
<padding>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</padding></Label>
|
||||
<TableView prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
|
||||
<columns>
|
||||
<TableColumn prefWidth="75.0" text="ID" />
|
||||
<TableColumn prefWidth="75.0" text="Type" />
|
||||
<TableColumn prefWidth="75.0" text="Owner" />
|
||||
<TableColumn prefWidth="75.0" styleClass="first-column" text="Local Ccy" />
|
||||
<TableColumn prefWidth="75.0" text="Amount">
|
||||
<styleClass>
|
||||
<String fx:value="second-column" />
|
||||
<String fx:value="monetary-value" />
|
||||
</styleClass>
|
||||
</TableColumn>
|
||||
<TableColumn prefWidth="75.0" text="USD Equiv" />
|
||||
</columns>
|
||||
<columnResizePolicy>
|
||||
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
|
||||
</columnResizePolicy>
|
||||
</TableView>
|
||||
</children>
|
||||
</VBox>
|
||||
<VBox prefHeight="200.0" prefWidth="100.0">
|
||||
<children>
|
||||
<Label text="Outputs: 24">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0" />
|
||||
</VBox.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" />
|
||||
</padding></Label>
|
||||
<TableView prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
|
||||
<columns>
|
||||
<TableColumn prefWidth="75.0" text="ID" />
|
||||
<TableColumn prefWidth="75.0" text="Type" />
|
||||
<TableColumn prefWidth="75.0" text="Owner" />
|
||||
<TableColumn prefWidth="75.0" styleClass="first-column" text="Local Ccy" />
|
||||
<TableColumn prefWidth="75.0" text="Amount">
|
||||
<styleClass>
|
||||
<String fx:value="second-column" />
|
||||
<String fx:value="monetary-value" />
|
||||
</styleClass>
|
||||
</TableColumn>
|
||||
<TableColumn prefWidth="75.0" text="USD Equiv" />
|
||||
</columns>
|
||||
<columnResizePolicy>
|
||||
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
|
||||
</columnResizePolicy>
|
||||
</TableView>
|
||||
</children>
|
||||
</VBox>
|
||||
</items>
|
||||
</SplitPane>
|
||||
</content>
|
||||
</TitledPane>
|
||||
<TitledPane prefHeight="200.0" prefWidth="200.0" text="Signatures (3/4)">
|
||||
<content>
|
||||
<TableView prefHeight="200.0" prefWidth="200.0">
|
||||
<columns>
|
||||
<TableColumn prefWidth="305.0" text="Signatory" />
|
||||
<TableColumn prefWidth="221.0" text="Status" />
|
||||
<TableColumn prefWidth="271.0" text="Status updated" />
|
||||
</columns>
|
||||
</TableView>
|
||||
</content>
|
||||
</TitledPane>
|
||||
<TitledPane prefHeight="54.0" prefWidth="722.0" text="Attachments (3)">
|
||||
<content>
|
||||
<TableView prefHeight="200.0" prefWidth="200.0">
|
||||
<columns>
|
||||
<TableColumn prefWidth="136.0" text="File name" />
|
||||
<TableColumn minWidth="8.0" prefWidth="172.0" text="Size" />
|
||||
<TableColumn prefWidth="218.0" text="Date modified" />
|
||||
</columns>
|
||||
</TableView>
|
||||
</content></TitledPane>
|
||||
<TitledPane animated="false" text="Low level events">
|
||||
<content>
|
||||
<TableView fx:id="LowLevelEventsTable">
|
||||
<columns>
|
||||
<TableColumn fx:id="LowLevelEventsTimestamp" prefWidth="102.0" text="Timestamp" />
|
||||
<TableColumn fx:id="LowLevelEventsEvent" prefWidth="138.0" text="Event" />
|
||||
</columns>
|
||||
</TableView>
|
||||
</content>
|
||||
</TitledPane>
|
||||
</panes>
|
||||
</Accordion>
|
||||
</VBox>
|
||||
<VBox prefHeight="200.0" prefWidth="100.0">
|
||||
<children>
|
||||
<Label text="Outputs: 24">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0" />
|
||||
</VBox.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<TableView fx:id="ContractStatesOutputStatesTable" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
|
||||
<columns>
|
||||
<TableColumn fx:id="ContractStatesOutputStatesId" prefWidth="75.0" text="ID" />
|
||||
<TableColumn fx:id="ContractStatesOutputStatesType" prefWidth="75.0" text="Type" />
|
||||
<TableColumn fx:id="ContractStatesOutputStatesOwner" prefWidth="75.0" text="Owner" />
|
||||
<TableColumn fx:id="ContractStatesOutputStatesLocalCurrency" prefWidth="75.0" styleClass="first-column" text="Local Ccy" />
|
||||
<TableColumn fx:id="ContractStatesOutputStatesAmount" prefWidth="75.0" text="Amount">
|
||||
<styleClass>
|
||||
<String fx:value="second-column" />
|
||||
<String fx:value="monetary-value" />
|
||||
</styleClass>
|
||||
</TableColumn>
|
||||
<TableColumn fx:id="ContractStatesOutputStatesEquiv" prefWidth="75.0" text="USD Equiv" />
|
||||
</columns>
|
||||
<columnResizePolicy>
|
||||
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
|
||||
</columnResizePolicy>
|
||||
</TableView>
|
||||
</children>
|
||||
</VBox>
|
||||
</items>
|
||||
</SplitPane>
|
||||
</content>
|
||||
</TitledPane>
|
||||
<TitledPane fx:id="SignaturesTitledPane" animated="false" text="Required signatures">
|
||||
<content>
|
||||
<ListView fx:id="SignaturesList" />
|
||||
</content>
|
||||
</TitledPane>
|
||||
<TitledPane fx:id="LowLevelEventsTitledPane" animated="false" text="Low level events">
|
||||
<content>
|
||||
<TableView fx:id="LowLevelEventsTable">
|
||||
<columns>
|
||||
<TableColumn fx:id="LowLevelEventsTimestamp" prefWidth="102.0" text="Timestamp" />
|
||||
<TableColumn fx:id="LowLevelEventsEvent" prefWidth="138.0" text="Event" />
|
||||
</columns>
|
||||
</TableView>
|
||||
</content>
|
||||
</TitledPane>
|
||||
</items>
|
||||
</SplitPane>
|
||||
<Label text="133 matching transaction(s)" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user