feat: Add RPC statistics screen to settings' advanced view
Closes #13264
This commit is contained in:
parent
b38138cc71
commit
1ac52f5d38
|
@ -220,7 +220,7 @@ proc newModule*[T](
|
||||||
result, events, accountsService, settingsService, stickersService,
|
result, events, accountsService, settingsService, stickersService,
|
||||||
profileService, contactsService, aboutService, languageService, privacyService, nodeConfigurationService,
|
profileService, contactsService, aboutService, languageService, privacyService, nodeConfigurationService,
|
||||||
devicesService, mailserversService, chatService, ensService, walletAccountService, generalService, communityService,
|
devicesService, mailserversService, chatService, ensService, walletAccountService, generalService, communityService,
|
||||||
networkService, keycardService, keychainService, tokenService
|
networkService, keycardService, keychainService, tokenService, nodeService
|
||||||
)
|
)
|
||||||
result.stickersModule = stickers_module.newModule(result, events, stickersService, settingsService, walletAccountService,
|
result.stickersModule = stickers_module.newModule(result, events, stickersService, settingsService, walletAccountService,
|
||||||
networkService, tokenService, keycardService)
|
networkService, tokenService, keycardService)
|
||||||
|
|
|
@ -23,6 +23,7 @@ import ../../../../app_service/service/community/service as community_service
|
||||||
import ../../../../app_service/service/keycard/service as keycard_service
|
import ../../../../app_service/service/keycard/service as keycard_service
|
||||||
import ../../../../app_service/service/keychain/service as keychain_service
|
import ../../../../app_service/service/keychain/service as keychain_service
|
||||||
import ../../../../app_service/service/token/service as token_service
|
import ../../../../app_service/service/token/service as token_service
|
||||||
|
import ../../../../app_service/service/node/service as node_service
|
||||||
|
|
||||||
import ./profile/module as profile_module
|
import ./profile/module as profile_module
|
||||||
import ./contacts/module as contacts_module
|
import ./contacts/module as contacts_module
|
||||||
|
@ -85,7 +86,8 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
|
||||||
networkService: network_service.Service,
|
networkService: network_service.Service,
|
||||||
keycardService: keycard_service.Service,
|
keycardService: keycard_service.Service,
|
||||||
keychainService: keychain_service.Service,
|
keychainService: keychain_service.Service,
|
||||||
tokenService: token_service.Service
|
tokenService: token_service.Service,
|
||||||
|
nodeService: node_service.Service
|
||||||
): Module =
|
): Module =
|
||||||
result = Module()
|
result = Module()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
|
@ -112,7 +114,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
|
||||||
privacyService, accountsService, walletAccountService, keychainService)
|
privacyService, accountsService, walletAccountService, keychainService)
|
||||||
|
|
||||||
result.walletModule = wallet_module.newModule(result, events, accountsService, walletAccountService, settingsService,
|
result.walletModule = wallet_module.newModule(result, events, accountsService, walletAccountService, settingsService,
|
||||||
networkService, devicesService)
|
networkService, devicesService, nodeService)
|
||||||
|
|
||||||
singletonInstance.engine.setRootContextProperty("profileSectionModule", result.viewVariant)
|
singletonInstance.engine.setRootContextProperty("profileSectionModule", result.viewVariant)
|
||||||
|
|
||||||
|
|
|
@ -2,22 +2,26 @@ import io_interface
|
||||||
import app/core/eventemitter
|
import app/core/eventemitter
|
||||||
import app_service/service/wallet_account/service as wallet_account_service
|
import app_service/service/wallet_account/service as wallet_account_service
|
||||||
import app_service/service/devices/service as devices_service
|
import app_service/service/devices/service as devices_service
|
||||||
|
import app_service/service/node/service as node_service
|
||||||
|
|
||||||
type
|
type
|
||||||
Controller* = ref object of RootObj
|
Controller* = ref object of RootObj
|
||||||
delegate: io_interface.AccessInterface
|
delegate: io_interface.AccessInterface
|
||||||
events: EventEmitter
|
events: EventEmitter
|
||||||
walletAccountService: wallet_account_service.Service
|
walletAccountService: wallet_account_service.Service
|
||||||
|
nodeService: node_service.Service
|
||||||
|
|
||||||
proc newController*(
|
proc newController*(
|
||||||
delegate: io_interface.AccessInterface,
|
delegate: io_interface.AccessInterface,
|
||||||
events: EventEmitter,
|
events: EventEmitter,
|
||||||
walletAccountService: wallet_account_service.Service,
|
walletAccountService: wallet_account_service.Service,
|
||||||
|
nodeService: node_service.Service
|
||||||
): Controller =
|
): Controller =
|
||||||
result = Controller()
|
result = Controller()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.events = events
|
result.events = events
|
||||||
result.walletAccountService = walletAccountService
|
result.walletAccountService = walletAccountService
|
||||||
|
result.nodeService = nodeService
|
||||||
|
|
||||||
proc delete*(self: Controller) =
|
proc delete*(self: Controller) =
|
||||||
discard
|
discard
|
||||||
|
@ -28,4 +32,10 @@ proc init*(self: Controller) =
|
||||||
self.delegate.onLocalPairingStatusUpdate(data)
|
self.delegate.onLocalPairingStatusUpdate(data)
|
||||||
|
|
||||||
proc hasPairedDevices*(self: Controller): bool =
|
proc hasPairedDevices*(self: Controller): bool =
|
||||||
return self.walletAccountService.hasPairedDevices()
|
return self.walletAccountService.hasPairedDevices()
|
||||||
|
|
||||||
|
proc getRpcStats*(self: Controller): string =
|
||||||
|
return self.nodeService.getRpcStats()
|
||||||
|
|
||||||
|
proc resetRpcStats*(self: Controller) =
|
||||||
|
self.nodeService.resetRpcStats()
|
||||||
|
|
|
@ -57,3 +57,9 @@ method hasPairedDevices*(self: AccessInterface): bool {.base.} =
|
||||||
|
|
||||||
method onLocalPairingStatusUpdate*(self: AccessInterface, data: LocalPairingStatus) {.base.} =
|
method onLocalPairingStatusUpdate*(self: AccessInterface, data: LocalPairingStatus) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getRpcStats*(self: AccessInterface): string {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method resetRpcStats*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
|
@ -15,6 +15,7 @@ import app_service/service/wallet_account/service as wallet_account_service
|
||||||
import app_service/service/network/service as network_service
|
import app_service/service/network/service as network_service
|
||||||
import app_service/service/settings/service as settings_service
|
import app_service/service/settings/service as settings_service
|
||||||
import app_service/service/devices/service as devices_service
|
import app_service/service/devices/service as devices_service
|
||||||
|
import app_service/service/node/service as node_service
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "profile-section-wallet-module"
|
topics = "profile-section-wallet-module"
|
||||||
|
@ -33,6 +34,7 @@ type
|
||||||
accountsService: accounts_service.Service
|
accountsService: accounts_service.Service
|
||||||
walletAccountService: wallet_account_service.Service
|
walletAccountService: wallet_account_service.Service
|
||||||
devicesService: devices_service.Service
|
devicesService: devices_service.Service
|
||||||
|
nodeService: node_service.Service
|
||||||
accountsModule: accounts_module.AccessInterface
|
accountsModule: accounts_module.AccessInterface
|
||||||
networksModule: networks_module.AccessInterface
|
networksModule: networks_module.AccessInterface
|
||||||
keypairImportModule: keypair_import_module.AccessInterface
|
keypairImportModule: keypair_import_module.AccessInterface
|
||||||
|
@ -44,11 +46,12 @@ proc newModule*(
|
||||||
walletAccountService: wallet_account_service.Service,
|
walletAccountService: wallet_account_service.Service,
|
||||||
settingsService: settings_service.Service,
|
settingsService: settings_service.Service,
|
||||||
networkService: network_service.Service,
|
networkService: network_service.Service,
|
||||||
devicesService: devices_service.Service
|
devicesService: devices_service.Service,
|
||||||
|
nodeService: node_service.Service
|
||||||
): Module =
|
): Module =
|
||||||
result = Module()
|
result = Module()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
result.controller = controller.newController(result, events, walletAccountService)
|
result.controller = controller.newController(result, events, walletAccountService, nodeService)
|
||||||
result.view = newView(result)
|
result.view = newView(result)
|
||||||
result.viewVariant = newQVariant(result.view)
|
result.viewVariant = newQVariant(result.view)
|
||||||
result.events = events
|
result.events = events
|
||||||
|
@ -132,4 +135,10 @@ method hasPairedDevices*(self: Module): bool =
|
||||||
|
|
||||||
method onLocalPairingStatusUpdate*(self: Module, data: LocalPairingStatus) =
|
method onLocalPairingStatusUpdate*(self: Module, data: LocalPairingStatus) =
|
||||||
if data.state == LocalPairingState.Finished:
|
if data.state == LocalPairingState.Finished:
|
||||||
self.view.emitHasPairedDevicesChangedSignal()
|
self.view.emitHasPairedDevicesChangedSignal()
|
||||||
|
|
||||||
|
method getRpcStats*(self: Module): string =
|
||||||
|
return self.controller.getRpcStats()
|
||||||
|
|
||||||
|
method resetRpcStats*(self: Module) =
|
||||||
|
self.controller.resetRpcStats()
|
||||||
|
|
|
@ -54,4 +54,9 @@ QtObject:
|
||||||
return self.delegate.hasPairedDevices()
|
return self.delegate.hasPairedDevices()
|
||||||
QtProperty[bool] hasPairedDevices:
|
QtProperty[bool] hasPairedDevices:
|
||||||
read = getHasPairedDevices
|
read = getHasPairedDevices
|
||||||
notify = hasPairedDevicesChanged
|
notify = hasPairedDevicesChanged
|
||||||
|
|
||||||
|
proc getRpcStats(self: View): string {.slot.} =
|
||||||
|
return self.delegate.getRpcStats()
|
||||||
|
proc resetRpcStats(self: View) {.slot.} =
|
||||||
|
self.delegate.resetRpcStats()
|
||||||
|
|
|
@ -114,3 +114,9 @@ method destroyKeypairImportPopup*(self: AccessInterface) {.base.} =
|
||||||
|
|
||||||
method hasPairedDevices*(self: AccessInterface): bool {.base.} =
|
method hasPairedDevices*(self: AccessInterface): bool {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getRpcStats*(self: AccessInterface): string {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method resetRpcStats*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
|
@ -445,3 +445,9 @@ method hasPairedDevices*(self: Module): bool =
|
||||||
proc onLocalPairingStatusUpdate*(self: Module, data: LocalPairingStatus) =
|
proc onLocalPairingStatusUpdate*(self: Module, data: LocalPairingStatus) =
|
||||||
if data.state == LocalPairingState.Finished:
|
if data.state == LocalPairingState.Finished:
|
||||||
self.view.emitHasPairedDevicesChangedSignal()
|
self.view.emitHasPairedDevicesChangedSignal()
|
||||||
|
|
||||||
|
method getRpcStats*(self: Module): string =
|
||||||
|
return self.view.getRpcStats()
|
||||||
|
|
||||||
|
method resetRpcStats*(self: Module) =
|
||||||
|
self.view.resetRpcStats()
|
||||||
|
|
|
@ -233,3 +233,8 @@ QtObject:
|
||||||
QtProperty[bool] walletReady:
|
QtProperty[bool] walletReady:
|
||||||
read = getWalletReady
|
read = getWalletReady
|
||||||
notify = walletReadyChanged
|
notify = walletReadyChanged
|
||||||
|
|
||||||
|
proc getRpcStats*(self: View): string {.slot.} =
|
||||||
|
return self.delegate.getRpcStats()
|
||||||
|
proc resetRpcStats*(self: View) {.slot.} =
|
||||||
|
self.delegate.resetRpcStats()
|
||||||
|
|
|
@ -68,4 +68,18 @@ QtObject:
|
||||||
|
|
||||||
proc peerCount*(self: Service): int = self.peers.len
|
proc peerCount*(self: Service): int = self.peers.len
|
||||||
|
|
||||||
proc isConnected*(self: Service): bool = self.connected
|
proc isConnected*(self: Service): bool = self.connected
|
||||||
|
|
||||||
|
proc getRpcStats*(self: Service): string =
|
||||||
|
try:
|
||||||
|
return status_node.getRpcStats()
|
||||||
|
except Exception as e:
|
||||||
|
let errDescription = e.msg
|
||||||
|
error "error: ", errDescription
|
||||||
|
|
||||||
|
proc resetRpcStats*(self: Service) =
|
||||||
|
try:
|
||||||
|
status_node.resetRpcStats()
|
||||||
|
except Exception as e:
|
||||||
|
let errDescription = e.msg
|
||||||
|
error "error: ", errDescription
|
||||||
|
|
|
@ -114,7 +114,6 @@ proc hasGas*(self: Service, accountAddress: string, chainId: int, nativeGasSymbo
|
||||||
if balance.account == accountAddress and balance.chainId == chainId:
|
if balance.account == accountAddress and balance.chainId == chainId:
|
||||||
if(self.currencyService.parseCurrencyValue(nativeGasSymbol, balance.balance) >= requiredGas):
|
if(self.currencyService.parseCurrencyValue(nativeGasSymbol, balance.balance) >= requiredGas):
|
||||||
return true
|
return true
|
||||||
break
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
proc getCurrency*(self: Service): string =
|
proc getCurrency*(self: Service): string =
|
||||||
|
|
|
@ -40,6 +40,20 @@ proc makePrivateRpcCall*(
|
||||||
error "error doing rpc request", methodName = methodName, exception=e.msg
|
error "error doing rpc request", methodName = methodName, exception=e.msg
|
||||||
raise newException(RpcException, e.msg)
|
raise newException(RpcException, e.msg)
|
||||||
|
|
||||||
|
proc makePrivateRpcCallNoDecode*(
|
||||||
|
methodName: string, inputJSON: JsonNode
|
||||||
|
): string {.raises: [RpcException].} =
|
||||||
|
if DB_BLOCKED_DUE_TO_PROFILE_MIGRATION:
|
||||||
|
debug "DB blocked due to profile migration, unable to proceed with the rpc call", rpc_method=methodName
|
||||||
|
raise newException(RpcException, "db closed due to profile migration")
|
||||||
|
try:
|
||||||
|
debug "NewBE_callPrivateRPCNoDecode", rpc_method=methodName
|
||||||
|
result = status_go.callPrivateRPC($inputJSON)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
error "error doing rpc request", methodName = methodName, exception=e.msg
|
||||||
|
raise newException(RpcException, e.msg)
|
||||||
|
|
||||||
proc callPrivateRPCWithChainId*(
|
proc callPrivateRPCWithChainId*(
|
||||||
methodName: string, chainId: int, payload = %* []
|
methodName: string, chainId: int, payload = %* []
|
||||||
): RpcResponse[JsonNode] {.raises: [RpcException, ValueError, Defect, SerializationError].} =
|
): RpcResponse[JsonNode] {.raises: [RpcException, ValueError, Defect, SerializationError].} =
|
||||||
|
@ -61,6 +75,16 @@ proc callPrivateRPC*(
|
||||||
}
|
}
|
||||||
return makePrivateRpcCall(methodName, inputJSON)
|
return makePrivateRpcCall(methodName, inputJSON)
|
||||||
|
|
||||||
|
proc callPrivateRPCNoDecode*(
|
||||||
|
methodName: string, payload = %* []
|
||||||
|
): string {.raises: [RpcException].} =
|
||||||
|
let inputJSON = %* {
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": methodName,
|
||||||
|
"params": %payload
|
||||||
|
}
|
||||||
|
return makePrivateRpcCallNoDecode(methodName, inputJSON)
|
||||||
|
|
||||||
proc migrateKeyStoreDir*(account: string, hashedPassword: string, oldKeystoreDir: string, multiaccountKeystoreDir: string)
|
proc migrateKeyStoreDir*(account: string, hashedPassword: string, oldKeystoreDir: string, multiaccountKeystoreDir: string)
|
||||||
{.raises: [RpcException, ValueError, Defect, SerializationError].} =
|
{.raises: [RpcException, ValueError, Defect, SerializationError].} =
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -14,3 +14,9 @@ proc wakuV2Peers*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
|
||||||
proc sendRPCMessageRaw*(inputJSON: string): string {.raises: [Exception].} =
|
proc sendRPCMessageRaw*(inputJSON: string): string {.raises: [Exception].} =
|
||||||
result = callPrivateRPCRaw(inputJSON)
|
result = callPrivateRPCRaw(inputJSON)
|
||||||
|
|
||||||
|
proc getRpcStats*(): string {.raises: [Exception].} =
|
||||||
|
result = callPrivateRPCNoDecode("rpcstats_getStats")
|
||||||
|
|
||||||
|
proc resetRpcStats*() {.raises: [Exception].} =
|
||||||
|
discard callPrivateRPCNoDecode("rpcstats_reset")
|
||||||
|
|
|
@ -293,6 +293,7 @@ StatusSectionLayout {
|
||||||
|
|
||||||
messagingStore: root.store.messagingStore
|
messagingStore: root.store.messagingStore
|
||||||
advancedStore: root.store.advancedStore
|
advancedStore: root.store.advancedStore
|
||||||
|
walletStore: root.store.walletStore
|
||||||
sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.advanced)
|
sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.advanced)
|
||||||
contentWidth: d.contentWidth
|
contentWidth: d.contentWidth
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,4 +148,12 @@ QtObject {
|
||||||
function updateWatchAccountHiddenFromTotalBalance(address, hideFromTotalBalance) {
|
function updateWatchAccountHiddenFromTotalBalance(address, hideFromTotalBalance) {
|
||||||
accountsModule.updateWatchAccountHiddenFromTotalBalance(address, hideFromTotalBalance)
|
accountsModule.updateWatchAccountHiddenFromTotalBalance(address, hideFromTotalBalance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRpcStats() {
|
||||||
|
return root.walletModule.getRpcStats()
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetRpcStats() {
|
||||||
|
root.walletModule.resetRpcStats()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ SettingsContentBase {
|
||||||
|
|
||||||
property MessagingStore messagingStore
|
property MessagingStore messagingStore
|
||||||
property AdvancedStore advancedStore
|
property AdvancedStore advancedStore
|
||||||
|
property WalletStore walletStore
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: advancedContainer
|
id: advancedContainer
|
||||||
|
@ -430,6 +431,14 @@ SettingsContentBase {
|
||||||
Global.openPopup(changeNumberOfLogsArchived)
|
Global.openPopup(changeNumberOfLogsArchived)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusSettingsLineButton {
|
||||||
|
id: rpcStatsButton
|
||||||
|
anchors.leftMargin: 0
|
||||||
|
anchors.rightMargin: 0
|
||||||
|
text: qsTr("RPC statistics")
|
||||||
|
onClicked: rpcStatsModal.open()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FleetsModal {
|
FleetsModal {
|
||||||
|
@ -618,5 +627,12 @@ SettingsContentBase {
|
||||||
onDecelerationChanged: root.advancedStore.setScrollDeceleration(value)
|
onDecelerationChanged: root.advancedStore.setScrollDeceleration(value)
|
||||||
onCustomScrollingChanged: root.advancedStore.setCustomScrollingEnabled(enabled)
|
onCustomScrollingChanged: root.advancedStore.setCustomScrollingEnabled(enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RPCStatsModal {
|
||||||
|
id: rpcStatsModal
|
||||||
|
|
||||||
|
walletStore: root.walletStore
|
||||||
|
title: rpcStatsButton.text
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQml 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQml.Models 2.15
|
||||||
|
|
||||||
|
import StatusQ 0.1
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
import StatusQ.Components 0.1
|
||||||
|
import StatusQ.Popups.Dialog 0.1
|
||||||
|
|
||||||
|
import shared.controls 1.0
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import "../stores"
|
||||||
|
|
||||||
|
|
||||||
|
StatusDialog {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
implicitHeight: 610
|
||||||
|
|
||||||
|
property WalletStore walletStore
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
|
||||||
|
property int totalCalls
|
||||||
|
property int totalFilteredCalls: countAggregator.value
|
||||||
|
|
||||||
|
function updateModel() {
|
||||||
|
sourceModel.clear()
|
||||||
|
|
||||||
|
const jsonStatsRaw = root.walletStore.getRpcStats()
|
||||||
|
const jsonStats = JSON.parse(jsonStatsRaw)
|
||||||
|
if (jsonStats.result && jsonStats.result.methods) {
|
||||||
|
const methods = jsonStats.result.methods
|
||||||
|
d.totalCalls = jsonStats.result.total
|
||||||
|
|
||||||
|
for (const method in methods) {
|
||||||
|
sourceModel.append({ method: method, count: methods[method] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetStats() {
|
||||||
|
root.walletStore.resetRpcStats()
|
||||||
|
updateModel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: contentColumn
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
SearchBox {
|
||||||
|
id: searchBox
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.bottomMargin: 16
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusListView {
|
||||||
|
id: resultsListView
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: sourceModel
|
||||||
|
}
|
||||||
|
|
||||||
|
header: StatusListItem {
|
||||||
|
title: qsTr("Total")
|
||||||
|
statusListItemTitle.customColor: Theme.palette.directColor1
|
||||||
|
statusListItemLabel.customColor: Theme.palette.directColor1
|
||||||
|
label: qsTr("%1 of %2").arg(d.totalFilteredCalls).arg(d.totalCalls)
|
||||||
|
enabled: false
|
||||||
|
z: 3 // Above delegate (z=1) and above section.delegate (z = 2)
|
||||||
|
}
|
||||||
|
headerPositioning: ListView.OverlayHeader
|
||||||
|
|
||||||
|
model: SortFilterProxyModel {
|
||||||
|
sourceModel: sourceModel
|
||||||
|
sorters: RoleSorter {
|
||||||
|
roleName: "count"
|
||||||
|
sortOrder: Qt.DescendingOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
filters: FastExpressionFilter {
|
||||||
|
function spellingTolerantSearch(data, searchKeyword) {
|
||||||
|
const regex = new RegExp(searchKeyword.split('').join('.{0,1}'), 'i')
|
||||||
|
return regex.test(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled: !!searchBox.text
|
||||||
|
expression: {
|
||||||
|
searchBox.text
|
||||||
|
let keyword = searchBox.text.trim().toUpperCase()
|
||||||
|
return spellingTolerantSearch(model.method, keyword)
|
||||||
|
}
|
||||||
|
expectedRoles: ["method"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SumAggregator {
|
||||||
|
id: countAggregator
|
||||||
|
|
||||||
|
model: resultsListView.model
|
||||||
|
roleName: "count"
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: StatusListItem {
|
||||||
|
title: model.method
|
||||||
|
label: model.count
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
d.updateModel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: StatusDialogFooter {
|
||||||
|
leftButtons: ObjectModel {
|
||||||
|
StatusButton {
|
||||||
|
text: qsTr("Refresh")
|
||||||
|
onClicked: {
|
||||||
|
d.updateModel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusButton {
|
||||||
|
text: qsTr("Reset")
|
||||||
|
onClicked: {
|
||||||
|
root.walletStore.resetRpcStats()
|
||||||
|
d.updateModel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rightButtons: ObjectModel {
|
||||||
|
CopyToClipBoardButton {
|
||||||
|
id: copyToClipboardButton
|
||||||
|
|
||||||
|
onCopyClicked: root.walletStore.copyToClipboard(textToCopy)
|
||||||
|
onPressed: function() {
|
||||||
|
let copiedText = "Total" + '\t' + d.totalFilteredCalls + " of " + d.totalCalls + '\n' + '\n'
|
||||||
|
for (let i = 0; i < resultsListView.model.count; i++) {
|
||||||
|
const item = resultsListView.model.get(i)
|
||||||
|
copiedText += item.method + '\t' + item.count + '\n'
|
||||||
|
}
|
||||||
|
textToCopy = copiedText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue