feat(MintToken): Add `delete` and `retry mint` options when deploy fails

- It refactors `SettingsPageLayout`.
- It adds `retry mint` and `delete` options when deploy process fails.
- It renames `RemotelyDestructAlertPopup` to generic name `AlertPopup`.
This commit is contained in:
Noelia 2023-05-30 17:18:45 +02:00 committed by Noelia
parent 8ae2d29a1c
commit d4d3a6d669
13 changed files with 171 additions and 63 deletions

View File

@ -194,7 +194,7 @@ ListModel {
section: "Popups" section: "Popups"
} }
ListElement { ListElement {
title: "RemotelyDestructAlertPopup" title: "AlertPopup"
section: "Popups" section: "Popups"
} }
ListElement { ListElement {

View File

@ -29,14 +29,16 @@ SplitView {
onClicked: dialog.open() onClicked: dialog.open()
} }
RemotelyDestructAlertPopup { AlertPopup {
id: dialog id: dialog
anchors.centerIn: parent anchors.centerIn: parent
tokenCount: 12 title: qsTr("Remotely destruct %n token(s)", "", 12)
acceptBtnText: qsTr("Remotely destruct")
alertText: qsTr("Continuing will destroy tokens held by members and revoke any perissions they given. To undo you will have to issue them new tokens.")
onRemotelyDestructClicked: logs.logEvent("RemotelyDestructAlertPopup::onRemotelyDestructClicked") onAcceptClicked: logs.logEvent("AlertPopup::onAcceptClicked")
onCancelClicked: logs.logEvent("RemotelyDestructAlertPopup::onCancelClicked") onCancelClicked: logs.logEvent("AlertPopup::onCancelClicked")
} }
} }

View File

@ -37,6 +37,8 @@ SplitView {
accounts: WalletAccountsModel {} accounts: WalletAccountsModel {}
onMintCollectible: logs.logEvent("CommunityMintTokensSettingsPanel::mintCollectible") onMintCollectible: logs.logEvent("CommunityMintTokensSettingsPanel::mintCollectible")
onMintAsset: logs.logEvent("CommunityMintTokensSettingsPanel::mintAssets")
onDeleteToken: logs.logEvent("CommunityMintTokensSettingsPanel::deleteToken: " + key)
} }
} }

View File

@ -92,4 +92,4 @@ community_welcome_screen_subtitle = {"container": statusDesktop_mainWindow, "obj
community_welcome_screen_checkList_element1 = {"container": statusDesktop_mainWindow, "objectName": "checkListText_0", "type": "StatusBaseText", "visible": True} community_welcome_screen_checkList_element1 = {"container": statusDesktop_mainWindow, "objectName": "checkListText_0", "type": "StatusBaseText", "visible": True}
community_welcome_screen_checkList_element2 = {"container": statusDesktop_mainWindow, "objectName": "checkListText_1", "type": "StatusBaseText", "visible": True} community_welcome_screen_checkList_element2 = {"container": statusDesktop_mainWindow, "objectName": "checkListText_1", "type": "StatusBaseText", "visible": True}
community_welcome_screen_checkList_element3 = {"container": statusDesktop_mainWindow, "objectName": "checkListText_2", "type": "StatusBaseText", "visible": True} community_welcome_screen_checkList_element3 = {"container": statusDesktop_mainWindow, "objectName": "checkListText_2", "type": "StatusBaseText", "visible": True}
community_welcome_screen_add_new_item = {"container": statusDesktop_mainWindow, "objectName": "addNewItemActionButton", "type": "StatusButton", "visible": True} community_welcome_screen_add_new_item = {"container": statusDesktop_mainWindow, "objectName": "primaryHeaderButton", "type": "StatusButton", "visible": True}

View File

@ -16,16 +16,15 @@ Item {
property alias title: itemHeader.text property alias title: itemHeader.text
property Component content property Component content
// optional // optional
property Component footer property Component footer
property bool dirty: false property bool dirty: false
property bool editable: false property bool editable: false
property bool headerButtonVisible: false property int headerWidth: d.defaultContentWidth
property string headerButtonText: ""
property int headerWidth: 0
property string previousPageName: "" property string previousPageName: ""
property bool saveChangesButtonEnabled: !!root.contentItem && !!root.contentItem.saveChangesButtonEnabled property bool saveChangesButtonEnabled: !!root.contentItem && !!root.contentItem.saveChangesButtonEnabled
property alias primaryHeaderButton: primaryHeaderBtn
property alias secondaryHeaderButton: secondaryHeaderBtn
property alias saveChangesText: settingsDirtyToastMessage.saveChangesText property alias saveChangesText: settingsDirtyToastMessage.saveChangesText
property alias cancelChangesText: settingsDirtyToastMessage.cancelChangesText property alias cancelChangesText: settingsDirtyToastMessage.cancelChangesText
property alias changesDetectedText: settingsDirtyToastMessage.changesDetectedText property alias changesDetectedText: settingsDirtyToastMessage.changesDetectedText
@ -38,7 +37,15 @@ Item {
signal saveChangesClicked signal saveChangesClicked
signal resetChangesClicked signal resetChangesClicked
signal headerButtonClicked signal primaryHeaderButtonClicked
signal secondaryHeaderButtonClicked
QtObject {
id: d
readonly property int leftMargin: 64
readonly property int defaultContentWidth: 560
}
function reloadContent() { function reloadContent() {
contentLoader.active = false contentLoader.active = false
@ -49,28 +56,29 @@ Item {
settingsDirtyToastMessage.notifyDirty() settingsDirtyToastMessage.notifyDirty()
} }
implicitWidth: layout.implicitWidth
implicitHeight: layout.implicitHeight implicitHeight: layout.implicitHeight
implicitWidth: layout.implicitWidth
ColumnLayout { ColumnLayout {
id: layout id: layout
anchors.fill: parent anchors.fill: parent
anchors.bottomMargin: 24
spacing: 16 spacing: 16
RowLayout { RowLayout {
Layout.maximumWidth: root.headerWidth === 0 ? parent.width : (root.headerWidth + itemHeader.Layout.leftMargin) Layout.leftMargin: d.leftMargin
Layout.preferredHeight: 56 Layout.maximumWidth: root.headerWidth
Layout.maximumHeight: 44
spacing: 9
RowLayout { RowLayout {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
Layout.fillWidth: true
StatusBaseText { StatusBaseText {
id: itemHeader id: itemHeader
Layout.leftMargin: 64
color: Theme.palette.directColor1 color: Theme.palette.directColor1
font.pixelSize: 26 font.pixelSize: 26
font.bold: true font.bold: true
@ -87,22 +95,40 @@ Item {
} }
} }
// Filler
Item {
Layout.fillWidth: true
}
StatusButton { StatusButton {
objectName: "addNewItemActionButton" id: secondaryHeaderBtn
visible: root.headerButtonVisible
text: root.headerButtonText Layout.fillHeight: true
Layout.preferredHeight: 44
Layout.alignment: Qt.AlignHCenter objectName: "secondaryHeaderButton"
onClicked: root.headerButtonClicked() visible: false
onClicked: root.secondaryHeaderButtonClicked()
}
StatusButton {
id: primaryHeaderBtn
Layout.fillHeight: true
objectName: "primaryHeaderButton"
visible: false
onClicked: root.primaryHeaderButtonClicked()
} }
} }
Loader { Loader {
id: contentLoader id: contentLoader
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
Layout.topMargin: 16 Layout.leftMargin: d.leftMargin
Layout.leftMargin: 64
Layout.rightMargin: 24 Layout.rightMargin: 24
sourceComponent: root.content sourceComponent: root.content

View File

@ -58,20 +58,18 @@ SettingsPageLayout {
name: d.welcomeViewState name: d.welcomeViewState
PropertyChanges {target: root; title: d.welcomePageTitle} PropertyChanges {target: root; title: d.welcomePageTitle}
PropertyChanges {target: root; previousPageName: ""} PropertyChanges {target: root; previousPageName: ""}
PropertyChanges {target: root; headerButtonVisible: true} PropertyChanges {target: root; primaryHeaderButton.visible: true}
PropertyChanges {target: root; headerButtonText: qsTr("New Airdrop")} PropertyChanges {target: root; primaryHeaderButton.text: qsTr("New Airdrop")}
PropertyChanges {target: root; headerWidth: root.viewWidth}
}, },
State { State {
name: d.newAirdropViewState name: d.newAirdropViewState
PropertyChanges {target: root; title: d.newAirdropViewPageTitle} PropertyChanges {target: root; title: d.newAirdropViewPageTitle}
PropertyChanges {target: root; previousPageName: d.welcomePageTitle} PropertyChanges {target: root; previousPageName: d.welcomePageTitle}
PropertyChanges {target: root; headerButtonVisible: false} PropertyChanges {target: root; primaryHeaderButton.visible: false}
PropertyChanges {target: root; headerWidth: 0}
} }
] ]
onHeaderButtonClicked: stackManager.push(d.newAirdropViewState, newAirdropView, null, StackView.Immediate) onPrimaryHeaderButtonClicked: stackManager.push(d.newAirdropViewState, newAirdropView, null, StackView.Immediate)
StackViewStates { StackViewStates {
id: stackManager id: stackManager

View File

@ -80,6 +80,10 @@ SettingsPageLayout {
signal airdropCollectible(string tokenKey) signal airdropCollectible(string tokenKey)
signal deleteToken(string tokenKey)
signal retryMintToken(string tokenKey)
function setFeeLoading() { function setFeeLoading() {
root.isFeeLoading = true root.isFeeLoading = true
root.feeText = "" root.feeText = ""
@ -124,6 +128,8 @@ SettingsPageLayout {
signal airdropClicked() signal airdropClicked()
signal retryMintClicked()
function updateInitialStackView() { function updateInitialStackView() {
if(stackManager.stackView) { if(stackManager.stackView) {
if(initialItem === welcomeView) if(initialItem === welcomeView)
@ -134,6 +140,8 @@ SettingsPageLayout {
} }
} }
secondaryHeaderButton.type: StatusBaseButton.Type.Danger
content: StackView { content: StackView {
anchors.fill: parent anchors.fill: parent
initialItem: d.initialItem initialItem: d.initialItem
@ -148,33 +156,42 @@ SettingsPageLayout {
PropertyChanges {target: root; title: d.welcomePageTitle} PropertyChanges {target: root; title: d.welcomePageTitle}
PropertyChanges {target: root; subTitle: ""} PropertyChanges {target: root; subTitle: ""}
PropertyChanges {target: root; previousPageName: ""} PropertyChanges {target: root; previousPageName: ""}
PropertyChanges {target: root; headerButtonVisible: true} PropertyChanges {target: root; primaryHeaderButton.visible: true}
PropertyChanges {target: root; headerButtonText: d.newTokenButtonText} PropertyChanges {target: root; primaryHeaderButton.text: d.newTokenButtonText}
PropertyChanges {target: root; headerWidth: root.viewWidth} PropertyChanges {target: root; secondaryHeaderButton.visible: false}
}, },
State { State {
name: d.newTokenViewState name: d.newTokenViewState
PropertyChanges {target: root; subTitle: ""} PropertyChanges {target: root; subTitle: ""}
PropertyChanges {target: root; previousPageName: d.backButtonText} PropertyChanges {target: root; previousPageName: d.backButtonText}
PropertyChanges {target: root; headerButtonVisible: false} PropertyChanges {target: root; primaryHeaderButton.visible: false}
PropertyChanges {target: root; headerWidth: 0} PropertyChanges {target: root; secondaryHeaderButton.visible: false}
}, },
State { State {
name: d.previewTokenViewState name: d.previewTokenViewState
PropertyChanges {target: root; previousPageName: d.backButtonText} PropertyChanges {target: root; previousPageName: d.backButtonText}
PropertyChanges {target: root; headerButtonVisible: false} PropertyChanges {target: root; primaryHeaderButton.visible: false}
PropertyChanges {target: root; headerWidth: 0} PropertyChanges {target: root; secondaryHeaderButton.visible: false}
}, },
State { State {
name: d.tokenViewState name: d.tokenViewState
PropertyChanges {target: root; previousPageName: d.backButtonText} PropertyChanges {target: root; previousPageName: d.backButtonText}
PropertyChanges {target: root; headerButtonVisible: false} PropertyChanges {target: root; primaryHeaderButton.visible: false}
PropertyChanges {target: root; headerWidth: 0}
PropertyChanges {target: root; footer: mintTokenFooter} PropertyChanges {target: root; footer: mintTokenFooter}
} }
] ]
onHeaderButtonClicked: stackManager.push(d.newTokenViewState, newTokenView, null, StackView.Immediate) onPrimaryHeaderButtonClicked: {
if(root.state == d.initialViewState)
stackManager.push(d.newTokenViewState, newTokenView, null, StackView.Immediate)
if(root.state == d.tokenViewState)
d.retryMintClicked()
}
onSecondaryHeaderButtonClicked: {
if(root.state == d.tokenViewState)
deleteTokenAlertPopup.open()
}
StackViewStates { StackViewStates {
id: stackManager id: stackManager
@ -421,10 +438,16 @@ SettingsPageLayout {
} }
} }
RemotelyDestructAlertPopup { AlertPopup {
id: alertPopup id: alertPopup
onRemotelyDestructClicked: { property int tokenCount
title: qsTr("Remotely destruct %n token(s)", "", tokenCount)
acceptBtnText: qsTr("Remotely destruct")
alertText: qsTr("Continuing will destroy tokens held by members and revoke any permissions they are given. To undo you will have to issue them new tokens.")
onAcceptClicked: {
signTransactionPopup.isRemotelyDestructTransaction = true signTransactionPopup.isRemotelyDestructTransaction = true
signTransactionPopup.open() signTransactionPopup.open()
} }
@ -501,6 +524,15 @@ SettingsPageLayout {
}, },
StackView.Immediate) StackView.Immediate)
} }
Connections {
target: d
function onRetryMintClicked() {
root.retryMintToken(d.tokenKey)
stackManager.clear(d.initialViewState, StackView.Immediate)
}
}
} }
} }
@ -527,6 +559,30 @@ SettingsPageLayout {
restoreMode: Binding.RestoreBindingOrValue restoreMode: Binding.RestoreBindingOrValue
} }
Binding {
target: root
property: "primaryHeaderButton.visible"
value: view.deployState === Constants.ContractTransactionStatus.Failed
}
Binding {
target: root
property: "primaryHeaderButton.text"
value: (view.deployState === Constants.ContractTransactionStatus.Failed) ? qsTr("Retry mint") : ""
}
Binding {
target: root
property: "secondaryHeaderButton.visible"
value: view.deployState === Constants.ContractTransactionStatus.Failed
}
Binding {
target: root
property: "secondaryHeaderButton.text"
value: (view.deployState === Constants.ContractTransactionStatus.Failed) ? qsTr("Delete") : ""
}
Binding { Binding {
target: d target: d
property: "tokenOwnersModel" property: "tokenOwnersModel"
@ -602,4 +658,19 @@ SettingsPageLayout {
} }
} }
} }
AlertPopup {
id: deleteTokenAlertPopup
width: 521
title: qsTr("Delete %1").arg(root.title)
acceptBtnText: qsTr("Delete %1 token").arg(root.title)
alertText: qsTr("%1 is not yet minted, are you sure you want to delete it? All data associated with this token including its icon and description will be permanently deleted.").arg(root.title)
onAcceptClicked: {
root.deleteToken(d.tokenKey)
stackManager.clear(d.initialViewState, StackView.Immediate)
}
onCancelClicked: close()
}
} }

View File

@ -97,38 +97,34 @@ SettingsPageLayout {
PropertyChanges {target: root; title: qsTr("Permissions")} PropertyChanges {target: root; title: qsTr("Permissions")}
PropertyChanges {target: root; previousPageName: ""} PropertyChanges {target: root; previousPageName: ""}
PropertyChanges {target: root; content: welcomeView} PropertyChanges {target: root; content: welcomeView}
PropertyChanges {target: root; headerButtonVisible: true} PropertyChanges {target: root; primaryHeaderButton.visible: true}
PropertyChanges {target: root; headerButtonText: qsTr("Add new permission")} PropertyChanges {target: root; primaryHeaderButton.text: qsTr("Add new permission")}
PropertyChanges {target: root; headerWidth: root.viewWidth}
}, },
State { State {
name: d.newPermissionViewState name: d.newPermissionViewState
PropertyChanges {target: root; title: qsTr("New permission")} PropertyChanges {target: root; title: qsTr("New permission")}
PropertyChanges {target: root; previousPageName: qsTr("Permissions")} PropertyChanges {target: root; previousPageName: qsTr("Permissions")}
PropertyChanges {target: root; content: newPermissionView} PropertyChanges {target: root; content: newPermissionView}
PropertyChanges {target: root; headerButtonVisible: false} PropertyChanges {target: root; primaryHeaderButton.visible: false}
PropertyChanges {target: root; headerWidth: 0}
}, },
State { State {
name: d.permissionsViewState name: d.permissionsViewState
PropertyChanges {target: root; title: qsTr("Permissions")} PropertyChanges {target: root; title: qsTr("Permissions")}
PropertyChanges {target: root; previousPageName: ""} PropertyChanges {target: root; previousPageName: ""}
PropertyChanges {target: root; content: permissionsView} PropertyChanges {target: root; content: permissionsView}
PropertyChanges {target: root; headerButtonVisible: true} PropertyChanges {target: root; primaryHeaderButton.visible: true}
PropertyChanges {target: root; headerButtonText: qsTr("Add new permission")} PropertyChanges {target: root; primaryHeaderButton.text: qsTr("Add new permission")}
PropertyChanges {target: root; headerWidth: root.viewWidth}
}, },
State { State {
name: d.editPermissionViewState name: d.editPermissionViewState
PropertyChanges {target: root; title: qsTr("Edit permission")} PropertyChanges {target: root; title: qsTr("Edit permission")}
PropertyChanges {target: root; previousPageName: qsTr("Permissions")} PropertyChanges {target: root; previousPageName: qsTr("Permissions")}
PropertyChanges {target: root; content: newPermissionView} PropertyChanges {target: root; content: newPermissionView}
PropertyChanges {target: root; headerButtonVisible: false} PropertyChanges {target: root; primaryHeaderButton.visible: false}
PropertyChanges {target: root; headerWidth: 0}
} }
] ]
onHeaderButtonClicked: { onPrimaryHeaderButtonClicked: {
if(root.state === d.welcomeViewState || root.state === d.permissionsViewState) { if(root.state === d.welcomeViewState || root.state === d.permissionsViewState) {
d.initializeData() d.initializeData()
root.state = d.newPermissionViewState root.state = d.newPermissionViewState

View File

@ -15,17 +15,18 @@ import utils 1.0
StatusDialog { StatusDialog {
id: root id: root
property int tokenCount: 0 property alias acceptBtnText: acceptBtn.text
property alias alertText: contentTextItem.text
signal remotelyDestructClicked signal acceptClicked
signal cancelClicked signal cancelClicked
title: qsTr("Remotely destruct %n token(s)", "", root.tokenCount)
implicitWidth: 400 // by design implicitWidth: 400 // by design
topPadding: Style.current.padding topPadding: Style.current.padding
bottomPadding: topPadding bottomPadding: topPadding
contentItem: StatusBaseText { contentItem: StatusBaseText {
text: qsTr("Continuing will destroy tokens held by members and revoke any perissions they given. To undo you will have to issue them new tokens.") id: contentTextItem
font.pixelSize: Style.current.primaryTextFontSize font.pixelSize: Style.current.primaryTextFontSize
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
lineHeight: 1.2 lineHeight: 1.2
@ -46,11 +47,12 @@ StatusDialog {
} }
StatusButton { StatusButton {
text: qsTr("Remotely destruct") id: acceptBtn
type: StatusBaseButton.Type.Danger type: StatusBaseButton.Type.Danger
onClicked: { onClicked: {
root.remotelyDestructClicked() root.acceptClicked()
close() close()
} }
} }

View File

@ -1,6 +1,6 @@
AlertPopup 1.0 AlertPopup.qml
BurnTokensPopup 1.0 BurnTokensPopup.qml BurnTokensPopup 1.0 BurnTokensPopup.qml
CreateChannelPopup 1.0 CreateChannelPopup.qml CreateChannelPopup 1.0 CreateChannelPopup.qml
CommunityTokenPermissionsPopup 1.0 CommunityTokenPermissionsPopup.qml CommunityTokenPermissionsPopup 1.0 CommunityTokenPermissionsPopup.qml
RemotelyDestructPopup 1.0 RemotelyDestructPopup.qml RemotelyDestructPopup 1.0 RemotelyDestructPopup.qml
RemotelyDestructAlertPopup 1.0 RemotelyDestructAlertPopup.qml
SignTokenTransactionsPopup 1.0 SignTokenTransactionsPopup.qml SignTokenTransactionsPopup 1.0 SignTokenTransactionsPopup.qml

View File

@ -343,6 +343,8 @@ StatusSectionLayout {
onSignBurnTransactionOpened: communityTokensStore.computeBurnFee(chainId) onSignBurnTransactionOpened: communityTokensStore.computeBurnFee(chainId)
onBurnCollectibles: communityTokensStore.burnCollectibles(tokenKey, amount) onBurnCollectibles: communityTokensStore.burnCollectibles(tokenKey, amount)
onAirdropCollectible: root.goTo(Constants.CommunitySettingsSections.Airdrops) onAirdropCollectible: root.goTo(Constants.CommunitySettingsSections.Airdrops)
onDeleteToken: communityTokensStore.deleteToken(root.community.id, tokenKey)
onRetryMintToken: communityTokensStore.retryMintToken(root.community.id, tokenKey)
Connections { Connections {
target: rootStore.communityTokensStore target: rootStore.communityTokensStore
@ -478,7 +480,7 @@ StatusSectionLayout {
function onAirdropCollectible(key) { function onAirdropCollectible(key) {
// Here it is forced a navigation to the new airdrop form, like if it was clicked the header button // Here it is forced a navigation to the new airdrop form, like if it was clicked the header button
airdropPanel.headerButtonClicked() airdropPanel.primaryHeaderButtonClicked()
// Force a token selection to be airdroped with default amount 1 // Force a token selection to be airdroped with default amount 1
airdropPanel.selectCollectible(key, 1) airdropPanel.selectCollectible(key, 1)

View File

@ -16,7 +16,8 @@ StatusScrollView {
property int imageWidth: 256 property int imageWidth: 256
property int imageHeigth: root.imageWidth property int imageHeigth: root.imageWidth
padding: 0
ColumnLayout { ColumnLayout {
id: mainLayout id: mainLayout

View File

@ -42,6 +42,14 @@ QtObject {
console.log("TODO: Deploy Asset backend!") console.log("TODO: Deploy Asset backend!")
} }
function deleteToken(communityId, contractUniqueKey) {
console.log("TODO: Delete token bakend!")
}
function retryMintToken(communityId, contractUniqueKey) {
console.log("TODO: Retry mint token bakend!")
}
readonly property Connections connections: Connections { readonly property Connections connections: Connections {
target: communityTokensModuleInst target: communityTokensModuleInst
function onDeployFeeUpdated(ethCurrency, fiatCurrency, errorCode) { function onDeployFeeUpdated(ethCurrency, fiatCurrency, errorCode) {