2024-10-15 19:26:12 +00:00
|
|
|
import QtQuick 2.15
|
|
|
|
import QtQuick.Controls 2.15
|
|
|
|
import QtQuick.Layouts 1.15
|
2022-11-25 17:35:30 +00:00
|
|
|
|
|
|
|
import StatusQ.Core 0.1
|
2024-10-15 19:26:12 +00:00
|
|
|
import StatusQ.Core.Theme 0.1
|
2022-11-25 17:35:30 +00:00
|
|
|
import StatusQ.Controls 0.1
|
|
|
|
import StatusQ.Components 0.1
|
|
|
|
import StatusQ.Core.Utils 0.1
|
|
|
|
|
|
|
|
Control{
|
|
|
|
id: root
|
|
|
|
|
2023-12-27 15:58:54 +00:00
|
|
|
objectName: "communityPermissionItem"
|
|
|
|
|
2022-11-25 17:35:30 +00:00
|
|
|
property var holdingsListModel
|
|
|
|
property var channelsListModel
|
2023-02-11 19:03:57 +00:00
|
|
|
|
|
|
|
property int permissionType: PermissionTypes.Type.None
|
2023-08-23 08:51:41 +00:00
|
|
|
property int permissionState: PermissionTypes.State.Approved
|
2022-11-25 17:35:30 +00:00
|
|
|
property bool isPrivate: false
|
2023-06-14 16:00:41 +00:00
|
|
|
property bool showButtons: true
|
2022-11-25 17:35:30 +00:00
|
|
|
|
|
|
|
signal editClicked
|
|
|
|
signal duplicateClicked
|
|
|
|
signal removeClicked
|
|
|
|
|
|
|
|
QtObject {
|
|
|
|
id: d
|
|
|
|
readonly property int flowRowHeight: 32
|
|
|
|
readonly property int commonMargin: 16
|
|
|
|
readonly property int designRadius: 16
|
|
|
|
readonly property int itemTextPixelSize: 17
|
|
|
|
readonly property int tagTextPixelSize: 15
|
|
|
|
readonly property int buttonTextPixelSize: 12
|
|
|
|
readonly property int buttonDiameter: 36
|
|
|
|
readonly property int buttonTextSpacing: 6
|
2023-08-08 16:17:24 +00:00
|
|
|
readonly property int headerIconleftMargin: 20
|
2023-08-23 08:51:41 +00:00
|
|
|
readonly property bool isActiveState: root.permissionState === PermissionTypes.State.Approved
|
|
|
|
readonly property bool isDeletingState: root.permissionState === PermissionTypes.State.RemovalPending
|
2023-08-08 16:17:24 +00:00
|
|
|
|
|
|
|
function getStateText(state) {
|
2023-08-23 08:51:41 +00:00
|
|
|
if(state === PermissionTypes.State.Approved)
|
2023-08-08 16:17:24 +00:00
|
|
|
return qsTr("Active")
|
|
|
|
|
2023-08-23 08:51:41 +00:00
|
|
|
if(state === PermissionTypes.State.AdditionPending)
|
2023-08-08 16:17:24 +00:00
|
|
|
return qsTr("Pending, will become active once owner node comes online")
|
|
|
|
|
2023-08-23 08:51:41 +00:00
|
|
|
if(state === PermissionTypes.State.RemovalPending)
|
2023-08-08 16:17:24 +00:00
|
|
|
return qsTr("Deletion pending, will be deleted once owner node comes online")
|
|
|
|
|
2023-08-23 08:51:41 +00:00
|
|
|
if(state === PermissionTypes.State.UpdatePending)
|
2023-08-08 16:17:24 +00:00
|
|
|
return qsTr("Pending updates will be applied when owner node comes online")
|
|
|
|
}
|
2022-11-25 17:35:30 +00:00
|
|
|
}
|
|
|
|
background: Rectangle {
|
|
|
|
color: "transparent"
|
|
|
|
border.color: Theme.palette.baseColor2
|
|
|
|
border.width: 1
|
|
|
|
radius: d.designRadius
|
|
|
|
}
|
|
|
|
|
|
|
|
contentItem: ColumnLayout {
|
|
|
|
spacing: 0
|
|
|
|
|
|
|
|
Rectangle {
|
|
|
|
id: header
|
|
|
|
color: Theme.palette.baseColor2
|
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.preferredHeight: 34
|
|
|
|
radius: d.designRadius
|
|
|
|
|
|
|
|
RowLayout {
|
|
|
|
anchors.fill: parent
|
|
|
|
spacing: 8
|
|
|
|
|
|
|
|
StatusIcon {
|
2023-08-08 16:17:24 +00:00
|
|
|
Layout.leftMargin: d.headerIconleftMargin
|
|
|
|
|
|
|
|
visible: d.isActiveState
|
2022-11-25 17:35:30 +00:00
|
|
|
icon: "checkmark"
|
|
|
|
Layout.preferredWidth: 11
|
|
|
|
Layout.preferredHeight: 8
|
|
|
|
color: Theme.palette.directColor1
|
|
|
|
}
|
|
|
|
|
2023-08-08 16:17:24 +00:00
|
|
|
StatusDotsLoadingIndicator {
|
|
|
|
Layout.leftMargin: d.headerIconleftMargin
|
|
|
|
|
|
|
|
visible: !d.isActiveState
|
|
|
|
}
|
|
|
|
|
2022-11-25 17:35:30 +00:00
|
|
|
StatusBaseText {
|
|
|
|
Layout.fillWidth: true
|
2023-08-08 16:17:24 +00:00
|
|
|
text: d.getStateText(root.permissionState)
|
2022-11-25 17:35:30 +00:00
|
|
|
font.pixelSize: d.tagTextPixelSize
|
|
|
|
}
|
|
|
|
|
|
|
|
StatusIcon {
|
|
|
|
Layout.rightMargin: 10
|
|
|
|
visible: root.isPrivate
|
|
|
|
icon: "hide"
|
|
|
|
color: Theme.palette.baseColor1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Flow {
|
|
|
|
id: content
|
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.fillHeight: true
|
|
|
|
Layout.topMargin: 8
|
|
|
|
Layout.rightMargin: d.commonMargin
|
|
|
|
Layout.leftMargin: d.commonMargin
|
|
|
|
Layout.bottomMargin: 20
|
|
|
|
spacing: 6
|
|
|
|
|
|
|
|
StatusBaseText {
|
|
|
|
font.pixelSize: d.itemTextPixelSize
|
|
|
|
height: d.flowRowHeight
|
2023-04-04 14:10:37 +00:00
|
|
|
text: holdingsRepeater.count > 0 ? qsTr("Anyone who holds")
|
|
|
|
: qsTr("Anyone")
|
2022-11-25 17:35:30 +00:00
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
|
|
}
|
|
|
|
|
|
|
|
Repeater {
|
2023-04-04 14:10:37 +00:00
|
|
|
id: holdingsRepeater
|
|
|
|
|
2022-11-25 17:35:30 +00:00
|
|
|
model: root.holdingsListModel
|
|
|
|
|
2023-01-12 11:31:08 +00:00
|
|
|
StatusListItemTag {
|
2023-12-28 15:10:09 +00:00
|
|
|
objectName: "whoHoldsStatusListItem"
|
2023-01-12 11:31:08 +00:00
|
|
|
height: d.flowRowHeight
|
|
|
|
width: (implicitWidth > content.width) ? content.width : implicitWidth
|
|
|
|
leftPadding: 2
|
|
|
|
title: model.text
|
|
|
|
asset.name: model.imageSource
|
2023-03-27 11:51:58 +00:00
|
|
|
asset.isImage: !model.isIcon
|
2023-01-12 11:31:08 +00:00
|
|
|
asset.bgColor: "transparent"
|
2023-03-27 11:51:58 +00:00
|
|
|
asset.color: asset.isImage ? "transparent" : titleText.color
|
2023-01-12 11:31:08 +00:00
|
|
|
asset.height: 28
|
|
|
|
asset.width: asset.height
|
2023-03-27 11:51:58 +00:00
|
|
|
asset.bgHeight: asset.height
|
|
|
|
asset.bgWidth: asset.height
|
2023-01-12 11:31:08 +00:00
|
|
|
closeButtonVisible: false
|
|
|
|
titleText.color: Theme.palette.primaryColor1
|
|
|
|
titleText.font.pixelSize: d.tagTextPixelSize
|
2022-11-25 17:35:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
StatusBaseText {
|
|
|
|
height: d.flowRowHeight
|
|
|
|
font.pixelSize: d.itemTextPixelSize
|
|
|
|
text: qsTr("is allowed to")
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
|
|
}
|
|
|
|
|
2023-08-22 18:09:34 +00:00
|
|
|
ListModel {
|
|
|
|
id: tokenOwnerModel
|
|
|
|
|
|
|
|
ListElement { permissionType: PermissionTypes.Type.Owner }
|
|
|
|
ListElement { permissionType: PermissionTypes.Type.TokenMaster }
|
|
|
|
ListElement { permissionType: PermissionTypes.Type.Admin }
|
|
|
|
}
|
|
|
|
|
|
|
|
ListModel {
|
|
|
|
id: tokenMasterModel
|
|
|
|
ListElement { permissionType: PermissionTypes.Type.TokenMaster }
|
|
|
|
ListElement { permissionType: PermissionTypes.Type.Admin }
|
|
|
|
}
|
|
|
|
|
|
|
|
ListModel {
|
|
|
|
id: regularRoleModel
|
|
|
|
ListElement { permissionType: PermissionTypes.Type.None }
|
|
|
|
}
|
|
|
|
|
|
|
|
Repeater {
|
|
|
|
id: rolesRepeater
|
|
|
|
|
|
|
|
model: {
|
|
|
|
if (root.permissionType === PermissionTypes.Type.Owner)
|
|
|
|
return tokenOwnerModel
|
|
|
|
if (root.permissionType === PermissionTypes.Type.TokenMaster)
|
|
|
|
return tokenMasterModel
|
|
|
|
return regularRoleModel
|
|
|
|
}
|
|
|
|
|
|
|
|
Flow {
|
|
|
|
spacing: 6
|
|
|
|
|
|
|
|
StatusListItemTag {
|
2023-12-28 15:10:09 +00:00
|
|
|
objectName: "isAllowedStatusListItem"
|
2023-08-22 18:09:34 +00:00
|
|
|
height: d.flowRowHeight
|
|
|
|
title: PermissionTypes.getName(model.permissionType === PermissionTypes.Type.None
|
|
|
|
? root.permissionType : model.permissionType)
|
|
|
|
asset.name: PermissionTypes.getIcon(root.permissionType)
|
|
|
|
asset.isImage: false
|
|
|
|
asset.bgColor: "transparent"
|
|
|
|
closeButtonVisible: false
|
|
|
|
titleText.color: Theme.palette.primaryColor1
|
|
|
|
titleText.font.pixelSize: d.tagTextPixelSize
|
|
|
|
}
|
|
|
|
|
|
|
|
StatusBaseText {
|
|
|
|
height: d.flowRowHeight
|
|
|
|
visible: model.index < rolesRepeater.model.count - 1
|
|
|
|
font.pixelSize: d.itemTextPixelSize
|
|
|
|
text: qsTr("and")
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2022-11-25 17:35:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
StatusBaseText {
|
|
|
|
height: d.flowRowHeight
|
|
|
|
font.pixelSize: d.itemTextPixelSize
|
|
|
|
text: qsTr("in")
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
|
|
|
}
|
|
|
|
|
|
|
|
Repeater {
|
|
|
|
model: root.channelsListModel
|
|
|
|
|
2023-01-12 09:11:09 +00:00
|
|
|
StatusListItemTag {
|
2023-12-28 15:10:09 +00:00
|
|
|
objectName: "inCommunityStatusListItem"
|
2023-01-27 09:22:04 +00:00
|
|
|
readonly property bool isLetterIdenticon: !model.imageSource
|
|
|
|
|
|
|
|
asset.isLetterIdenticon: isLetterIdenticon
|
|
|
|
asset.emoji: model.emoji ? model.emoji : ""
|
|
|
|
asset.color: model.color ? model.color : ""
|
|
|
|
asset.width: isLetterIdenticon ? 20 : 28
|
|
|
|
asset.height: asset.width
|
|
|
|
|
|
|
|
leftPadding: isLetterIdenticon ? 6 : 2
|
|
|
|
|
2023-01-12 09:11:09 +00:00
|
|
|
height: d.flowRowHeight
|
2023-01-27 09:22:04 +00:00
|
|
|
width: (implicitWidth > content.width)
|
|
|
|
? content.width : implicitWidth
|
|
|
|
|
2023-01-12 09:11:09 +00:00
|
|
|
title: model.text
|
2023-01-27 09:22:04 +00:00
|
|
|
asset.name: model.imageSource ? model.imageSource : ""
|
2023-01-12 09:11:09 +00:00
|
|
|
asset.isImage: true
|
|
|
|
asset.bgColor: "transparent"
|
|
|
|
closeButtonVisible: false
|
|
|
|
titleText.color: Theme.palette.primaryColor1
|
|
|
|
titleText.font.pixelSize: d.tagTextPixelSize
|
2022-11-25 17:35:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RowLayout {
|
|
|
|
id: footer
|
2023-06-14 16:00:41 +00:00
|
|
|
visible: root.showButtons
|
2022-11-25 17:35:30 +00:00
|
|
|
spacing: 85
|
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.bottomMargin: d.commonMargin
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
|
|
|
|
|
|
ColumnLayout {
|
|
|
|
spacing: d.buttonTextSpacing
|
|
|
|
StatusRoundButton {
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
|
|
icon.name: "edit_pencil"
|
|
|
|
Layout.preferredHeight: d.buttonDiameter
|
|
|
|
Layout.preferredWidth: Layout.preferredHeight
|
|
|
|
type: StatusRoundButton.Type.Primary
|
|
|
|
onClicked: root.editClicked()
|
2023-08-23 08:51:41 +00:00
|
|
|
|
|
|
|
// FIXME: implement undo operation first
|
|
|
|
enabled: d.isActiveState
|
2022-11-25 17:35:30 +00:00
|
|
|
}
|
|
|
|
StatusBaseText {
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
|
|
text: qsTr("Edit")
|
|
|
|
color: Theme.palette.primaryColor1
|
|
|
|
font.pixelSize: d.buttonTextPixelSize
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ColumnLayout {
|
|
|
|
spacing: d.buttonTextSpacing
|
|
|
|
StatusRoundButton {
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
|
|
icon.name: "copy"
|
|
|
|
Layout.preferredHeight: d.buttonDiameter
|
|
|
|
Layout.preferredWidth: Layout.preferredHeight
|
|
|
|
type: StatusRoundButton.Type.Primary
|
|
|
|
onClicked: root.duplicateClicked()
|
|
|
|
}
|
|
|
|
StatusBaseText {
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
|
|
text: qsTr("Duplicate")
|
|
|
|
color: Theme.palette.primaryColor1
|
|
|
|
font.pixelSize: d.buttonTextPixelSize
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ColumnLayout {
|
|
|
|
spacing: d.buttonTextSpacing
|
|
|
|
StatusRoundButton {
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
|
|
icon.name: "delete"
|
|
|
|
Layout.preferredHeight: d.buttonDiameter
|
|
|
|
Layout.preferredWidth: Layout.preferredHeight
|
|
|
|
type: StatusRoundButton.Type.Quaternary
|
|
|
|
onClicked: root.removeClicked()
|
2023-08-23 08:51:41 +00:00
|
|
|
|
|
|
|
// FIXME: implement undo operation first
|
|
|
|
enabled: d.isActiveState
|
2022-11-25 17:35:30 +00:00
|
|
|
}
|
|
|
|
StatusBaseText {
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
2023-08-23 08:51:41 +00:00
|
|
|
text: /*d.isDeletingState*/false ? qsTr("Undo delete") : qsTr("Delete")
|
2022-11-25 17:35:30 +00:00
|
|
|
color: Theme.palette.dangerColor1
|
|
|
|
font.pixelSize: d.buttonTextPixelSize
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|