feat(@desktop/wallet): Part implementation of the filter activity UI
This commit is contained in:
parent
a4731517d6
commit
ff98144a56
|
@ -349,4 +349,8 @@ ListModel {
|
|||
title: "StatusTxProgressBar"
|
||||
section: "Wallet"
|
||||
}
|
||||
ListElement {
|
||||
title: "ActivityFilterMenu"
|
||||
section: "Wallet"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
import AppLayouts.Wallet.popups 1.0
|
||||
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
import Storybook 1.0
|
||||
|
||||
import Models 1.0
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
Logs { id: logs }
|
||||
|
||||
orientation: Qt.Vertical
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property int selectedTime: ActivityPeriodFilterSubMenu.All
|
||||
function changeSelectedTime(newTime) {
|
||||
selectedTime = newTime
|
||||
}
|
||||
function setCustomTimeRange(fromTimestamp , toTimestamp) {
|
||||
dialog.fromTimestamp = fromTimestamp
|
||||
dialog.toTimestamp = toTimestamp
|
||||
}
|
||||
property var typeFilters: [
|
||||
ActivityTypeFilterSubMenu.Send,
|
||||
ActivityTypeFilterSubMenu.Receive,
|
||||
ActivityTypeFilterSubMenu.Buy,
|
||||
ActivityTypeFilterSubMenu.Swap,
|
||||
ActivityTypeFilterSubMenu.Bridge]
|
||||
}
|
||||
|
||||
Item {
|
||||
SplitView.fillWidth: true
|
||||
SplitView.fillHeight: true
|
||||
|
||||
StatusRoundButton {
|
||||
id: filterButton
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 100
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 32
|
||||
height: 32
|
||||
border.width: 1
|
||||
border.color: Theme.palette.directColor8
|
||||
type: StatusRoundButton.Type.Tertiary
|
||||
icon.name: "filter"
|
||||
onClicked: {
|
||||
activityFilterMenu.popup(filterButton.x, filterButton.y + filterButton.height + 4)
|
||||
}
|
||||
}
|
||||
ActivityFilterMenu {
|
||||
id: activityFilterMenu
|
||||
|
||||
selectedTime: d.selectedTime
|
||||
onSetSelectedTime: {
|
||||
if(selectedTime === ActivityPeriodFilterSubMenu.Custom) {
|
||||
dialog.open()
|
||||
}
|
||||
d.changeSelectedTime(selectedTime)
|
||||
}
|
||||
|
||||
typeFilters: d.typeFilters
|
||||
onUpdateTypeFilter: console.warn("onUpdateTypeFilter:: type :: ", type, " checked ::", checked)
|
||||
}
|
||||
|
||||
|
||||
StatusDateRangePicker {
|
||||
id: dialog
|
||||
anchors.centerIn: parent
|
||||
destroyOnClose: false
|
||||
fromTimestamp: new Date().setDate(new Date().getDate() - 7) // 7 days ago
|
||||
onNewRangeSet: {
|
||||
d.setCustomTimeRange(fromTimestamp, toTimestamp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogsAndControlsPanel {
|
||||
id: logsAndControlsPanel
|
||||
|
||||
SplitView.minimumHeight: 100
|
||||
SplitView.preferredHeight: 200
|
||||
|
||||
logsView.logText: logs.logText
|
||||
|
||||
ButtonGroup {
|
||||
buttons: periodRow.children
|
||||
}
|
||||
|
||||
Column {
|
||||
spacing: 20
|
||||
|
||||
Row {
|
||||
id: periodRow
|
||||
spacing: 20
|
||||
|
||||
RadioButton {
|
||||
checked: true
|
||||
text: "All"
|
||||
onCheckedChanged: if(checked) { d.selectedTime = ActivityPeriodFilterSubMenu.All}
|
||||
}
|
||||
RadioButton {
|
||||
text: "Today"
|
||||
onCheckedChanged: if(checked) { d.selectedTime = ActivityPeriodFilterSubMenu.Today}
|
||||
}
|
||||
RadioButton {
|
||||
text: "Yesterday"
|
||||
onCheckedChanged: if(checked) { d.selectedTime = ActivityPeriodFilterSubMenu.Yesterday}
|
||||
}
|
||||
RadioButton {
|
||||
text: "ThisWeek"
|
||||
onCheckedChanged: if(checked) { d.selectedTime = ActivityPeriodFilterSubMenu.ThisWeek}
|
||||
}
|
||||
RadioButton {
|
||||
text: "LastWeek"
|
||||
onCheckedChanged: if(checked) { d.selectedTime = ActivityPeriodFilterSubMenu.LastWeek}
|
||||
}
|
||||
RadioButton {
|
||||
text: "ThisMonth"
|
||||
onCheckedChanged: if(checked) { d.selectedTime = ActivityPeriodFilterSubMenu.ThisMonth}
|
||||
}
|
||||
RadioButton {
|
||||
text: "LastMonth"
|
||||
onCheckedChanged: if(checked) { d.selectedTime = ActivityPeriodFilterSubMenu.LastMonth}
|
||||
}
|
||||
RadioButton {
|
||||
text: "Custom"
|
||||
onCheckedChanged: if(checked) { d.selectedTime = ActivityPeriodFilterSubMenu.Custom}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: 20
|
||||
CheckBox {
|
||||
id: sendCheckbox
|
||||
text: "Send"
|
||||
checked: true
|
||||
}
|
||||
CheckBox {
|
||||
id: receiveCheckbox
|
||||
text: "Receive"
|
||||
checked: true
|
||||
}
|
||||
CheckBox {
|
||||
id: buyCheckbox
|
||||
text: "Buy"
|
||||
checked: true
|
||||
}
|
||||
CheckBox {
|
||||
id: swapCheckbox
|
||||
text: "Swap"
|
||||
checked: true
|
||||
}
|
||||
CheckBox {
|
||||
id: bridgeCheckbox
|
||||
text: "Bridge"
|
||||
checked: true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
StatusMenuItem {
|
||||
arrow: StatusIcon {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 16
|
||||
height: 16
|
||||
icon: "next"
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
StatusListItem {
|
||||
id: root
|
||||
|
||||
property bool checked: true
|
||||
property bool allChecked : false
|
||||
property ButtonGroup buttonGroup
|
||||
|
||||
signal actionTriggered(bool checked)
|
||||
|
||||
height: 44
|
||||
radius: 0
|
||||
leftPadding: 21
|
||||
rightPadding: 21
|
||||
asset.width: 24
|
||||
asset.height: 24
|
||||
asset.bgWidth: 0
|
||||
asset.bgHeight: 0
|
||||
statusListItemTitle.font.pixelSize: 13
|
||||
ButtonGroup.group: buttonGroup
|
||||
onClicked: checkBox.nextCheckState()
|
||||
components: [
|
||||
StatusCheckBox {
|
||||
id: checkBox
|
||||
tristate: true
|
||||
spacing: 0
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
checkState: allChecked ? Qt.PartiallyChecked : root.checked ? Qt.Checked : Qt.Unchecked
|
||||
nextCheckState: function() {
|
||||
root.actionTriggered(checkBox.checked)
|
||||
return Qt.PartiallyChecked
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
StatusIconTextButton {
|
||||
id: root
|
||||
implicitHeight: 34
|
||||
spacing: 2
|
||||
leftPadding: 10
|
||||
statusIcon: "tiny/chevron-left"
|
||||
icon.width: 18
|
||||
icon.height: 18
|
||||
font.pixelSize: 13
|
||||
text: qsTr("Back")
|
||||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
color: root.hovered ? Theme.palette.baseColor2 : Theme.palette.statusModal.backgroundColor
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.12
|
||||
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
StatusRadioButton {
|
||||
id: root
|
||||
implicitHeight: 34
|
||||
contentItem: StatusBaseText {
|
||||
width: parent.width
|
||||
font.pixelSize: 13
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
color: Theme.palette.directColor1
|
||||
leftPadding: 14
|
||||
rightPadding: 24
|
||||
text: root.text
|
||||
}
|
||||
indicator: StatusIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 10
|
||||
icon: "checkbox"
|
||||
width: 12
|
||||
height: 12
|
||||
color: Theme.palette.primaryColor1
|
||||
visible: root.checked
|
||||
}
|
||||
background: Rectangle {
|
||||
color: root.hovered ? Theme.palette.baseColor2 : Theme.palette.statusModal.backgroundColor
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
import "../controls"
|
||||
import "./filterSubMenus"
|
||||
|
||||
StatusMenu {
|
||||
id: root
|
||||
|
||||
// Time filter
|
||||
property int selectedTime: ActivityFilterMenu.All
|
||||
signal setSelectedTime(int selectedTime)
|
||||
|
||||
// Type filter
|
||||
property var typeFilters: []
|
||||
signal updateTypeFilter(int type, bool checked)
|
||||
|
||||
implicitWidth: 176
|
||||
|
||||
// Filter By Period
|
||||
ActivityFilterMenuItem {
|
||||
text: qsTr("Period")
|
||||
onTriggered: timeMenu.popup(Qt.point(0, -8))
|
||||
|
||||
// just to be able to place the submenus within an Item
|
||||
ActivityPeriodFilterSubMenu {
|
||||
id: timeMenu
|
||||
onBack: root.open()
|
||||
onActionTriggered: {
|
||||
timeMenu.close()
|
||||
setSelectedTime(action)
|
||||
}
|
||||
selectedTime: root.selectedTime
|
||||
}
|
||||
ActivityTypeFilterSubMenu {
|
||||
id: typeMenu
|
||||
onBack: root.open()
|
||||
typeFilters: root.typeFilters
|
||||
onActionTriggered: updateTypeFilter(action, checked)
|
||||
}
|
||||
}
|
||||
|
||||
ActivityFilterMenuItem {
|
||||
text: qsTr("Type")
|
||||
onTriggered: typeMenu.popup(Qt.point(0, -8))
|
||||
}
|
||||
|
||||
ActivityFilterMenuItem {
|
||||
text: qsTr("Status")
|
||||
}
|
||||
|
||||
ActivityFilterMenuItem {
|
||||
text: qsTr("Tokens")
|
||||
}
|
||||
|
||||
ActivityFilterMenuItem {
|
||||
text: qsTr("Counterparty")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
import "../../controls"
|
||||
|
||||
StatusMenu {
|
||||
id: root
|
||||
|
||||
property int selectedTime: ActivityFilterMenu.All
|
||||
|
||||
signal back()
|
||||
signal actionTriggered(int action)
|
||||
|
||||
enum TimePeriod {
|
||||
All,
|
||||
Today,
|
||||
Yesterday,
|
||||
ThisWeek,
|
||||
LastWeek,
|
||||
ThisMonth,
|
||||
LastMonth,
|
||||
Custom
|
||||
}
|
||||
|
||||
MenuBackButton {
|
||||
width: parent.width
|
||||
onClicked: {
|
||||
close()
|
||||
back()
|
||||
}
|
||||
}
|
||||
StatusWalletMenuRadioButton {
|
||||
checked: root.selectedTime === ActivityPeriodFilterSubMenu.All
|
||||
text: qsTr("All time")
|
||||
onClicked: actionTriggered(ActivityPeriodFilterSubMenu.All)
|
||||
}
|
||||
StatusWalletMenuRadioButton {
|
||||
checked: root.selectedTime === ActivityPeriodFilterSubMenu.Today
|
||||
text: qsTr("Today")
|
||||
onClicked: actionTriggered(ActivityPeriodFilterSubMenu.Today)
|
||||
}
|
||||
StatusWalletMenuRadioButton {
|
||||
checked: root.selectedTime === ActivityPeriodFilterSubMenu.Yesterday
|
||||
text: qsTr("Yesterday")
|
||||
onClicked: actionTriggered(ActivityPeriodFilterSubMenu.Yesterday)
|
||||
}
|
||||
StatusWalletMenuRadioButton {
|
||||
checked: root.selectedTime === ActivityPeriodFilterSubMenu.ThisWeek
|
||||
text: qsTr("This week")
|
||||
onClicked: actionTriggered(ActivityPeriodFilterSubMenu.ThisWeek)
|
||||
}
|
||||
StatusWalletMenuRadioButton {
|
||||
checked: root.selectedTime === ActivityPeriodFilterSubMenu.LastWeek
|
||||
text: qsTr("Last week")
|
||||
onClicked: actionTriggered(ActivityPeriodFilterSubMenu.LastWeek)
|
||||
}
|
||||
StatusWalletMenuRadioButton {
|
||||
checked: root.selectedTime === ActivityPeriodFilterSubMenu.ThisMonth
|
||||
text: qsTr("This month")
|
||||
onClicked: actionTriggered(ActivityPeriodFilterSubMenu.ThisMonth)
|
||||
}
|
||||
StatusWalletMenuRadioButton {
|
||||
checked: root.selectedTime === ActivityPeriodFilterSubMenu.LastMonth
|
||||
text: qsTr("Last month")
|
||||
onClicked: actionTriggered(ActivityPeriodFilterSubMenu.LastMonth)
|
||||
}
|
||||
StatusMenuSeparator {}
|
||||
StatusWalletMenuRadioButton {
|
||||
checked: root.selectedTime === ActivityPeriodFilterSubMenu.Custom
|
||||
text: qsTr("Custom range")
|
||||
onClicked: actionTriggered(ActivityPeriodFilterSubMenu.Custom)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
import "../../controls"
|
||||
|
||||
StatusMenu {
|
||||
id: root
|
||||
|
||||
property var typeFilters:[]
|
||||
|
||||
signal back()
|
||||
signal actionTriggered(int action, bool checked)
|
||||
|
||||
property bool allChecked: {
|
||||
let allCheckedIs = true
|
||||
for(var i=0;i< root.contentChildren.length;i++) {
|
||||
if(root.contentChildren[i].checkState === Qt.Unchecked)
|
||||
allCheckedIs = false
|
||||
}
|
||||
return allCheckedIs
|
||||
}
|
||||
|
||||
enum TxType {
|
||||
Send,
|
||||
Receive,
|
||||
Buy,
|
||||
Swap,
|
||||
Bridge
|
||||
}
|
||||
|
||||
MenuBackButton {
|
||||
width: parent.width
|
||||
onClicked: {
|
||||
close()
|
||||
back()
|
||||
}
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: typeButtonGroup
|
||||
exclusive: false
|
||||
}
|
||||
|
||||
ActivityTypeCheckBox {
|
||||
title: qsTr("Send")
|
||||
asset.name: "send"
|
||||
checked: typeFilters.includes(ActivityTypeFilterSubMenu.Send)
|
||||
buttonGroup: typeButtonGroup
|
||||
onActionTriggered: root.actionTriggered(ActivityTypeFilterSubMenu.Send, checked)
|
||||
allChecked: root.allChecked
|
||||
}
|
||||
ActivityTypeCheckBox {
|
||||
title: qsTr("Receive")
|
||||
asset.name: "receive"
|
||||
buttonGroup: typeButtonGroup
|
||||
checked: typeFilters.includes(ActivityTypeFilterSubMenu.Receive)
|
||||
onActionTriggered: root.actionTriggered(ActivityTypeFilterSubMenu.Receive, checked)
|
||||
allChecked: root.allChecked
|
||||
}
|
||||
ActivityTypeCheckBox {
|
||||
title: qsTr("Buy")
|
||||
asset.name: "token"
|
||||
buttonGroup: typeButtonGroup
|
||||
checked: typeFilters.includes(ActivityTypeFilterSubMenu.Buy)
|
||||
onActionTriggered: root.actionTriggered(ActivityTypeFilterSubMenu.Buy, checked)
|
||||
allChecked: root.allChecked
|
||||
}
|
||||
ActivityTypeCheckBox {
|
||||
title: qsTr("Swap")
|
||||
asset.name: "swap"
|
||||
buttonGroup: typeButtonGroup
|
||||
checked: typeFilters.includes(ActivityTypeFilterSubMenu.Swap)
|
||||
onActionTriggered: root.actionTriggered(ActivityTypeFilterSubMenu.Swap, checked)
|
||||
allChecked: root.allChecked
|
||||
}
|
||||
ActivityTypeCheckBox {
|
||||
title: qsTr("Bridge")
|
||||
asset.name: "bridge"
|
||||
buttonGroup: typeButtonGroup
|
||||
checked: typeFilters.includes(ActivityTypeFilterSubMenu.Bridge)
|
||||
onActionTriggered: root.actionTriggered(ActivityTypeFilterSubMenu.Bridge, checked)
|
||||
allChecked: root.allChecked
|
||||
}
|
||||
}
|
|
@ -1 +1,4 @@
|
|||
NetworkSelectPopup 1.0 NetworkSelectPopup.qml
|
||||
NetworkSelectPopup 1.0 NetworkSelectPopup.qml
|
||||
ActivityFilterMenu 1.0 ActivityFilterMenu.qml
|
||||
ActivityPeriodFilterSubMenu 1.0 filterSubMenus/ActivityPeriodFilterSubMenu.qml
|
||||
ActivityTypeFilterSubMenu 1.0 filterSubMenus/ActivityTypeFilterSubMenu.qml
|
||||
|
|
|
@ -19,6 +19,8 @@ import "../stores"
|
|||
import "../controls"
|
||||
|
||||
import AppLayouts.Wallet.stores 1.0 as WalletStores
|
||||
import AppLayouts.Wallet.popups 1.0
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
@ -68,6 +70,30 @@ ColumnLayout {
|
|||
text: qsTr("Activity for this account will appear here")
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: filterComponent
|
||||
visible: !d.isLoading && transactionListRoot.count !== 0
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 50
|
||||
color: Theme.palette.transparent
|
||||
StatusRoundButton {
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 32
|
||||
height: 32
|
||||
border.width: 1
|
||||
border.color: Theme.palette.directColor8
|
||||
icon.name: "filter"
|
||||
onClicked: activityFilter.popup(x, y + height + 4)
|
||||
type: StatusRoundButton.Type.Tertiary
|
||||
}
|
||||
}
|
||||
|
||||
Separator {
|
||||
Layout.fillWidth: true
|
||||
visible: filterComponent.visible
|
||||
}
|
||||
|
||||
StatusListView {
|
||||
id: transactionListRoot
|
||||
objectName: "walletAccountTransactionList"
|
||||
|
@ -161,6 +187,7 @@ ColumnLayout {
|
|||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
implicitHeight: 1
|
||||
visible: !sectionDelegate.isFirstSection
|
||||
}
|
||||
|
||||
StatusTextWithLoadingState {
|
||||
|
@ -312,4 +339,23 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ActivityFilterMenu {
|
||||
id: activityFilter
|
||||
selectedTime: ActivityPeriodFilterSubMenu.All
|
||||
onSetSelectedTime: {
|
||||
// To do connect with n=backend to set time range
|
||||
if(selectedTime === ActivityPeriodFilterSubMenu.Custom) {
|
||||
customDateRangePicker.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// To-do update once https://github.com/status-im/status-desktop/pull/10916 is updated and connect with backend values
|
||||
StatusDateRangePicker {
|
||||
id: customDateRangePicker
|
||||
destroyOnClose: false
|
||||
fromTimestamp: new Date().setDate(new Date().getDate() - 7)
|
||||
// onNewRangeSet: d.setCustomTimeRange(fromTimestamp, toTimestamp)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue