status-desktop/ui/app/AppLayouts/Communities/panels/PermissionsSettingsPanel.qml

353 lines
12 KiB
QML
Raw Normal View History

import QtQuick 2.14
import AppLayouts.Communities.controls 1.0
import AppLayouts.Communities.layouts 1.0
import AppLayouts.Chat.stores 1.0
import AppLayouts.Communities.views 1.0
import StatusQ.Core.Utils 0.1
import utils 1.0
SettingsPageLayout {
id: root
required property var permissionsModel
required property var assetsModel
required property var collectiblesModel
required property var channelsModel
// id, name, image, color, owner properties expected
required property var communityDetails
property int viewWidth: 560 // by design
signal createPermissionRequested(
int permissionType, var holdings, var channels, bool isPrivate)
signal updatePermissionRequested(
string key, int permissionType, var holdings, var channels, bool isPrivate)
signal removePermissionRequested(string key)
signal navigateToMintTokenSettings
function navigateBack() {
if (root.state === d.newPermissionViewState) {
root.state = d.initialState
} else if (root.state === d.permissionsViewState) {
root.state = d.newPermissionViewState
} else if (root.state === d.editPermissionViewState) {
if (root.dirty) {
root.notifyDirty()
} else {
root.state = d.initialState
}
}
}
QtObject {
id: d
readonly property string welcomeViewState: "WELCOME"
readonly property string newPermissionViewState: "NEW_PERMISSION"
readonly property string permissionsViewState: "PERMISSIONS"
readonly property string editPermissionViewState: "EDIT_PERMISSION"
readonly property bool permissionsExist: root.permissionsModel.count > 0
signal saveChanges
signal resetChanges
property string permissionKeyToEdit
property var holdingsToEditModel
property int permissionTypeToEdit: PermissionTypes.Type.None
property var channelsToEditModel
property bool isPrivateToEditValue: false
onPermissionsExistChanged: {
// Navigate back to welcome permissions view if all existing permissions are removed.
if(root.state === d.permissionsViewState && !permissionsExist) {
root.state = d.welcomeViewState;
}
}
readonly property string initialState: d.permissionsExist ? d.permissionsViewState : d.welcomeViewState
function initializeData() {
holdingsToEditModel = emptyModel
channelsToEditModel = emptyModel
permissionTypeToEdit = PermissionTypes.Type.None
isPrivateToEditValue = false
}
}
saveChangesButtonEnabled: true
saveChangesText: qsTr("Update permission")
cancelChangesText: qsTr("Revert changes")
state: d.initialState
states: [
State {
name: d.welcomeViewState
PropertyChanges {target: root; title: qsTr("Permissions")}
PropertyChanges {target: root; previousPageName: ""}
PropertyChanges {target: root; content: welcomeView}
PropertyChanges {target: root; primaryHeaderButton.visible: true}
PropertyChanges {target: root; primaryHeaderButton.text: qsTr("Add new permission")}
},
State {
name: d.newPermissionViewState
PropertyChanges {target: root; title: qsTr("New permission")}
PropertyChanges {target: root; previousPageName: qsTr("Permissions")}
PropertyChanges {target: root; content: newPermissionView}
PropertyChanges {target: root; primaryHeaderButton.visible: false}
},
State {
name: d.permissionsViewState
PropertyChanges {target: root; title: qsTr("Permissions")}
PropertyChanges {target: root; previousPageName: ""}
PropertyChanges {target: root; content: permissionsView}
PropertyChanges {target: root; primaryHeaderButton.visible: true}
PropertyChanges {target: root; primaryHeaderButton.text: qsTr("Add new permission")}
},
State {
name: d.editPermissionViewState
PropertyChanges {target: root; title: qsTr("Edit permission")}
PropertyChanges {target: root; previousPageName: qsTr("Permissions")}
PropertyChanges {target: root; content: newPermissionView}
PropertyChanges {target: root; primaryHeaderButton.visible: false}
}
]
onPrimaryHeaderButtonClicked: {
if(root.state === d.welcomeViewState || root.state === d.permissionsViewState) {
d.initializeData()
root.state = d.newPermissionViewState
}
}
onSaveChangesClicked: {
d.saveChanges()
d.resetChanges()
root.navigateBack()
}
onResetChangesClicked: {
d.resetChanges()
root.navigateBack()
}
// Community Permissions possible view contents:
Component {
id: welcomeView
WelcomeSettingsView {
viewWidth: root.viewWidth
image: Style.png("community/permissions2_3")
title: qsTr("Permissions")
subtitle: qsTr("You can manage your community by creating and issuing membership and access permissions")
checkersModel: [
qsTr("Give individual members access to private channels"),
qsTr("Monetise your community with subscriptions and fees"),
qsTr("Require holding a token or NFT to obtain exclusive membership rights")
]
}
}
Component {
id: newPermissionView
EditPermissionView {
id: editPermissionView
viewWidth: root.viewWidth
assetsModel: root.assetsModel
collectiblesModel: root.collectiblesModel
channelsModel: root.channelsModel
communityDetails: root.communityDetails
isEditState: root.state === d.editPermissionViewState
selectedHoldingsModel: d.holdingsToEditModel
selectedChannelsModel: d.channelsToEditModel
permissionType: d.permissionTypeToEdit
isPrivate: d.isPrivateToEditValue
holdingsRequired: selectedHoldingsModel ? selectedHoldingsModel.count > 0
: false
permissionDuplicated: {
// dependencies
holdingsTracker.revision
channelsTracker.revision
editPermissionView.dirtyValues.permissionType
editPermissionView.dirtyValues.isPrivate
const model = root.permissionsModel
const count = model.rowCount()
for (let i = 0; i < count; i++) {
const item = ModelUtils.get(model, i)
if (root.state === d.editPermissionViewState
&& d.permissionKeyToEdit === item.key)
continue
const holdings = item.holdingsListModel
const channels = item.channelsListModel
const permissionType = item.permissionType
const same = (a, b) => ModelUtils.checkEqualitySet(a, b, ["key"])
if (holdings.rowCount() === 0)
if (dirtyValues.holdingsRequired)
continue
else
return true
if (holdings.rowCount() !== 0 && !dirtyValues.holdingsRequired)
continue
if (same(dirtyValues.selectedHoldingsModel, holdings)
&& same(dirtyValues.selectedChannelsModel, channels)
&& dirtyValues.permissionType === permissionType)
return true
}
return false
}
permissionTypeLimitReached: {
const type = dirtyValues.permissionType
const limit = PermissionTypes.getPermissionsCountLimit(type)
if (limit === -1)
return false
const model = root.permissionsModel
const count = model.rowCount()
let sameTypeCount = 0
for (let i = 0; i < count; i++)
if (type === ModelUtils.get(model, i, "permissionType"))
sameTypeCount++
return limit <= sameTypeCount
}
onCreatePermissionClicked: {
const holdings = dirtyValues.holdingsRequired ?
ModelUtils.modelToArray(
dirtyValues.selectedHoldingsModel,
["key", "type", "amount"])
: []
const channels = ModelUtils.modelToArray(
dirtyValues.selectedChannelsModel, ["key"])
root.createPermissionRequested(
dirtyValues.permissionType, holdings, channels,
dirtyValues.isPrivate)
root.state = d.permissionsViewState
}
onNavigateToMintTokenSettings: root.navigateToMintTokenSettings()
Connections {
target: d
function onSaveChanges() {
const holdings = dirtyValues.holdingsRequired ?
ModelUtils.modelToArray(
dirtyValues.selectedHoldingsModel,
["key", "type", "amount"])
: []
const channels = ModelUtils.modelToArray(
dirtyValues.selectedChannelsModel, ["key"])
root.updatePermissionRequested(
d.permissionKeyToEdit, dirtyValues.permissionType,
holdings, channels, dirtyValues.isPrivate)
}
function onResetChanges() {
resetChanges()
}
}
Binding {
target: root
property: "dirty"
value: isEditState && dirty
}
ModelChangeTracker {
id: holdingsTracker
model: editPermissionView.dirtyValues.selectedHoldingsModel
}
ModelChangeTracker {
id: channelsTracker
model: editPermissionView.dirtyValues.selectedChannelsModel
}
Binding {
target: root
property: "saveChangesButtonEnabled"
value: !editPermissionView.permissionDuplicated
&& !editPermissionView.permissionTypeLimitReached
&& editPermissionView.isFullyFilled
}
}
}
Component {
id: permissionsView
PermissionsView {
permissionsModel: root.permissionsModel
assetsModel: root.assetsModel
collectiblesModel: root.collectiblesModel
channelsModel: root.channelsModel
communityDetails: root.communityDetails
viewWidth: root.viewWidth
function setInitialValuesFromIndex(index) {
const item = ModelUtils.get(root.permissionsModel, index)
d.holdingsToEditModel = item.holdingsListModel
d.channelsToEditModel = item.channelsListModel
d.permissionTypeToEdit = item.permissionType
d.isPrivateToEditValue = item.isPrivate
}
onEditPermissionRequested: {
setInitialValuesFromIndex(index)
d.permissionKeyToEdit = ModelUtils.get(
root.permissionsModel, index, "key")
root.state = d.editPermissionViewState
}
onDuplicatePermissionRequested: {
setInitialValuesFromIndex(index)
root.state = d.newPermissionViewState
}
onRemovePermissionRequested: {
const key = ModelUtils.get(root.permissionsModel, index, "key")
root.removePermissionRequested(key)
}
}
}
ListModel {
id: emptyModel
}
}