2023-05-06 06:52:23 +03:00
|
|
|
import QtQuick
|
2023-06-13 20:03:20 +09:00
|
|
|
import QtQuick.Controls
|
|
|
|
|
import QtQuick.Layouts
|
|
|
|
|
import QtQuick.Dialogs
|
2023-05-06 06:52:23 +03:00
|
|
|
|
2023-06-13 20:03:20 +09:00
|
|
|
import SortFilterProxyModel 0.2
|
2023-05-06 06:52:23 +03:00
|
|
|
|
2023-06-13 20:03:20 +09:00
|
|
|
import PageEnum 1.0
|
|
|
|
|
import ContainerProps 1.0
|
2024-07-07 13:42:38 +03:00
|
|
|
import Style 1.0
|
2023-06-13 20:03:20 +09:00
|
|
|
|
|
|
|
|
import "./"
|
|
|
|
|
import "../Controls2"
|
|
|
|
|
import "../Controls2/TextTypes"
|
|
|
|
|
import "../Components"
|
2024-04-01 20:20:02 +07:00
|
|
|
import "../Config"
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2025-08-01 17:02:12 +04:00
|
|
|
|
2023-06-13 20:03:20 +09:00
|
|
|
PageType {
|
|
|
|
|
id: root
|
|
|
|
|
|
2023-07-05 10:15:38 +09:00
|
|
|
enum ConfigType {
|
|
|
|
|
AmneziaConnection,
|
|
|
|
|
OpenVpn,
|
2023-10-30 14:20:21 +05:00
|
|
|
WireGuard,
|
2024-02-23 19:55:59 +02:00
|
|
|
Awg,
|
2024-03-27 11:02:34 +00:00
|
|
|
Xray
|
2023-07-05 10:15:38 +09:00
|
|
|
}
|
|
|
|
|
|
2023-06-13 20:03:20 +09:00
|
|
|
Connections {
|
|
|
|
|
target: ExportController
|
|
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
function onRevokeConfigFinished() {
|
2025-09-03 06:56:08 +03:00
|
|
|
PageController.showBusyIndicator(false)
|
|
|
|
|
PageController.showNotificationMessage(qsTr("Config revoked"))
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-05 10:15:38 +09:00
|
|
|
function onGenerateConfig(type) {
|
2023-07-04 09:58:19 +09:00
|
|
|
PageController.showBusyIndicator(true)
|
2023-07-05 10:15:38 +09:00
|
|
|
|
2025-08-27 16:41:11 +08:00
|
|
|
var configCaption
|
|
|
|
|
var configExtension
|
|
|
|
|
var configFileName
|
|
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
var containerIndex = ServersUiController.processedContainerIndex
|
2026-05-28 10:57:08 +08:00
|
|
|
var serverId = ServersUiController.processedServerId
|
2026-04-30 14:53:03 +08:00
|
|
|
|
2023-07-05 10:15:38 +09:00
|
|
|
switch (type) {
|
2024-02-23 19:55:59 +02:00
|
|
|
case PageShare.ConfigType.AmneziaConnection: {
|
2026-05-15 12:33:36 +08:00
|
|
|
ExportController.generateConnectionConfig(serverId, containerIndex, clientNameTextField.textField.text);
|
2025-08-27 16:41:11 +08:00
|
|
|
configCaption = qsTr("Save AmneziaVPN config")
|
|
|
|
|
configExtension = ".vpn"
|
|
|
|
|
configFileName = "amnezia_config"
|
2024-02-23 19:55:59 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2023-08-22 14:37:29 +05:00
|
|
|
case PageShare.ConfigType.OpenVpn: {
|
2026-05-15 12:33:36 +08:00
|
|
|
ExportController.generateOpenVpnConfig(serverId, clientNameTextField.textField.text)
|
2025-08-27 16:41:11 +08:00
|
|
|
configCaption = qsTr("Save OpenVPN config")
|
|
|
|
|
configExtension = ".ovpn"
|
|
|
|
|
configFileName = "amnezia_for_openvpn"
|
2023-10-30 14:20:21 +05:00
|
|
|
break
|
2023-08-22 14:37:29 +05:00
|
|
|
}
|
|
|
|
|
case PageShare.ConfigType.WireGuard: {
|
2026-05-15 12:33:36 +08:00
|
|
|
ExportController.generateWireGuardConfig(serverId, clientNameTextField.textField.text)
|
2025-08-27 16:41:11 +08:00
|
|
|
configCaption = qsTr("Save WireGuard config")
|
|
|
|
|
configExtension = ".conf"
|
|
|
|
|
configFileName = "amnezia_for_wireguard"
|
2023-10-30 14:20:21 +05:00
|
|
|
break
|
|
|
|
|
}
|
2024-02-23 19:55:59 +02:00
|
|
|
case PageShare.ConfigType.Awg: {
|
2026-05-15 12:33:36 +08:00
|
|
|
ExportController.generateAwgConfig(serverId, containerIndex, clientNameTextField.textField.text)
|
2025-08-27 16:41:11 +08:00
|
|
|
configCaption = qsTr("Save AmneziaWG config")
|
|
|
|
|
configExtension = ".conf"
|
|
|
|
|
configFileName = "amnezia_for_awg"
|
2024-02-23 19:55:59 +02:00
|
|
|
break
|
|
|
|
|
}
|
2024-03-27 11:02:34 +00:00
|
|
|
case PageShare.ConfigType.Xray: {
|
2026-05-15 12:33:36 +08:00
|
|
|
ExportController.generateXrayConfig(serverId, clientNameTextField.textField.text)
|
2025-08-27 16:41:11 +08:00
|
|
|
configCaption = qsTr("Save XRay config")
|
|
|
|
|
configExtension = ".json"
|
|
|
|
|
configFileName = "amnezia_for_xray"
|
2024-03-27 11:02:34 +00:00
|
|
|
break
|
|
|
|
|
}
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
2023-07-05 10:15:38 +09:00
|
|
|
|
2023-07-04 09:58:19 +09:00
|
|
|
PageController.showBusyIndicator(false)
|
2025-08-01 17:02:12 +04:00
|
|
|
|
2025-08-27 16:41:11 +08:00
|
|
|
var headerText = qsTr("Connection to ") + serverSelector.text
|
|
|
|
|
var configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
|
|
|
|
PageController.goToShareConnectionPage(headerText, configContentHeaderText, configCaption, configExtension, configFileName)
|
2023-07-04 09:58:19 +09:00
|
|
|
}
|
|
|
|
|
|
2024-05-25 13:00:51 +03:00
|
|
|
function onExportErrorOccurred(error) {
|
|
|
|
|
PageController.showErrorMessage(error)
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 14:32:16 +07:00
|
|
|
property bool isSearchBarVisible: false
|
2023-06-13 20:03:20 +09:00
|
|
|
property bool showContent: false
|
2023-07-31 00:13:08 +09:00
|
|
|
property bool shareButtonEnabled: true
|
2023-06-13 20:03:20 +09:00
|
|
|
property list<QtObject> connectionTypesModel: [
|
|
|
|
|
amneziaConnectionFormat
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
QtObject {
|
|
|
|
|
id: amneziaConnectionFormat
|
2024-12-31 04:16:52 +01:00
|
|
|
readonly property string name: qsTr("For the AmneziaVPN app")
|
|
|
|
|
readonly property int type: PageShare.ConfigType.AmneziaConnection
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
QtObject {
|
|
|
|
|
id: openVpnConnectionFormat
|
2024-12-31 04:16:52 +01:00
|
|
|
readonly property string name: qsTr("OpenVPN native format")
|
|
|
|
|
readonly property int type: PageShare.ConfigType.OpenVpn
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
QtObject {
|
|
|
|
|
id: wireGuardConnectionFormat
|
2024-12-31 04:16:52 +01:00
|
|
|
readonly property string name: qsTr("WireGuard native format")
|
|
|
|
|
readonly property int type: PageShare.ConfigType.WireGuard
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
2024-02-23 19:55:59 +02:00
|
|
|
QtObject {
|
|
|
|
|
id: awgConnectionFormat
|
2024-12-31 04:16:52 +01:00
|
|
|
readonly property string name: qsTr("AmneziaWG native format")
|
|
|
|
|
readonly property int type: PageShare.ConfigType.Awg
|
2024-02-23 19:55:59 +02:00
|
|
|
}
|
2024-03-27 11:02:34 +00:00
|
|
|
QtObject {
|
|
|
|
|
id: xrayConnectionFormat
|
2024-12-31 04:16:52 +01:00
|
|
|
readonly property string name: qsTr("XRay native format")
|
|
|
|
|
readonly property int type: PageShare.ConfigType.Xray
|
2024-03-27 11:02:34 +00:00
|
|
|
}
|
2023-06-13 20:03:20 +09:00
|
|
|
|
|
|
|
|
FlickableType {
|
2024-04-18 17:54:55 +04:00
|
|
|
id: a
|
|
|
|
|
|
2023-06-20 10:25:24 +09:00
|
|
|
anchors.top: parent.top
|
|
|
|
|
anchors.bottom: parent.bottom
|
2024-02-17 23:09:05 +02:00
|
|
|
contentHeight: content.height + 10
|
2023-06-13 20:03:20 +09:00
|
|
|
|
|
|
|
|
ColumnLayout {
|
|
|
|
|
id: content
|
|
|
|
|
|
|
|
|
|
anchors.top: parent.top
|
|
|
|
|
anchors.left: parent.left
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
|
|
|
|
|
|
anchors.rightMargin: 16
|
|
|
|
|
anchors.leftMargin: 16
|
|
|
|
|
|
2023-08-26 10:08:50 +03:00
|
|
|
spacing: 0
|
|
|
|
|
|
2025-05-02 23:54:36 -07:00
|
|
|
HeaderTypeWithButton {
|
2024-04-18 17:54:55 +04:00
|
|
|
id: header
|
2023-06-13 20:03:20 +09:00
|
|
|
Layout.fillWidth: true
|
2026-04-30 14:53:03 +08:00
|
|
|
Layout.topMargin: 24 + PageController.safeAreaTopMargin
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-10-21 18:32:30 +01:00
|
|
|
headerText: qsTr("Share VPN Access")
|
2023-11-23 00:03:43 +07:00
|
|
|
|
|
|
|
|
actionButtonImage: "qrc:/images/controls/more-vertical.svg"
|
|
|
|
|
actionButtonFunction: function() {
|
2024-12-31 04:16:52 +01:00
|
|
|
shareFullAccessDrawer.openTriggered()
|
2023-11-23 00:03:43 +07:00
|
|
|
}
|
|
|
|
|
|
2024-02-16 15:24:06 +05:00
|
|
|
DrawerType2 {
|
2023-11-23 00:03:43 +07:00
|
|
|
id: shareFullAccessDrawer
|
|
|
|
|
|
2024-02-16 15:24:06 +05:00
|
|
|
parent: root
|
2023-11-23 00:03:43 +07:00
|
|
|
|
2024-02-16 15:24:06 +05:00
|
|
|
anchors.fill: parent
|
2024-07-11 16:36:24 +07:00
|
|
|
expandedHeight: root.height
|
2023-11-23 00:03:43 +07:00
|
|
|
|
2024-12-31 04:16:52 +01:00
|
|
|
expandedStateContent: ColumnLayout {
|
2024-07-11 16:36:24 +07:00
|
|
|
id: shareFullAccessDrawerContent
|
2023-11-23 00:03:43 +07:00
|
|
|
anchors.top: parent.top
|
|
|
|
|
anchors.left: parent.left
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
|
anchors.topMargin: 16
|
|
|
|
|
|
|
|
|
|
spacing: 0
|
|
|
|
|
|
2024-07-11 16:36:24 +07:00
|
|
|
onImplicitHeightChanged: {
|
|
|
|
|
shareFullAccessDrawer.expandedHeight = shareFullAccessDrawerContent.implicitHeight + 32
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 00:03:43 +07:00
|
|
|
Header2Type {
|
|
|
|
|
Layout.fillWidth: true
|
|
|
|
|
Layout.bottomMargin: 16
|
|
|
|
|
Layout.leftMargin: 16
|
|
|
|
|
Layout.rightMargin: 16
|
|
|
|
|
|
|
|
|
|
headerText: qsTr("Share full access to the server and VPN")
|
|
|
|
|
descriptionText: qsTr("Use for your own devices, or share with those you trust to manage the server.")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LabelWithButtonType {
|
2024-04-18 17:54:55 +04:00
|
|
|
id: shareFullAccessButton
|
2023-11-23 00:03:43 +07:00
|
|
|
Layout.fillWidth: true
|
|
|
|
|
|
|
|
|
|
text: qsTr("Share")
|
|
|
|
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
|
|
|
|
|
|
|
|
|
clickedFunction: function() {
|
|
|
|
|
PageController.goToPage(PageEnum.PageShareFullAccess)
|
2024-12-31 04:16:52 +01:00
|
|
|
shareFullAccessDrawer.closeTriggered()
|
2023-11-23 00:03:43 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Rectangle {
|
|
|
|
|
id: accessTypeSelector
|
|
|
|
|
|
|
|
|
|
property int currentIndex
|
|
|
|
|
|
|
|
|
|
Layout.topMargin: 32
|
|
|
|
|
|
|
|
|
|
implicitWidth: accessTypeSelectorContent.implicitWidth
|
|
|
|
|
implicitHeight: accessTypeSelectorContent.implicitHeight
|
|
|
|
|
|
2024-08-20 16:54:05 +07:00
|
|
|
color: AmneziaStyle.color.onyxBlack
|
2023-06-13 20:03:20 +09:00
|
|
|
radius: 16
|
|
|
|
|
|
|
|
|
|
RowLayout {
|
|
|
|
|
id: accessTypeSelectorContent
|
|
|
|
|
|
|
|
|
|
spacing: 0
|
|
|
|
|
|
|
|
|
|
HorizontalRadioButton {
|
2024-04-18 17:54:55 +04:00
|
|
|
id: connectionRadioButton
|
2023-06-13 20:03:20 +09:00
|
|
|
checked: accessTypeSelector.currentIndex === 0
|
|
|
|
|
|
|
|
|
|
implicitWidth: (root.width - 32) / 2
|
|
|
|
|
text: qsTr("Connection")
|
|
|
|
|
|
|
|
|
|
onClicked: {
|
|
|
|
|
accessTypeSelector.currentIndex = 0
|
|
|
|
|
}
|
2025-08-01 05:56:02 +02:00
|
|
|
|
|
|
|
|
Keys.onEnterPressed: this.clicked()
|
|
|
|
|
Keys.onReturnPressed: this.clicked()
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HorizontalRadioButton {
|
2024-04-18 17:54:55 +04:00
|
|
|
id: usersRadioButton
|
2023-11-21 20:13:51 +07:00
|
|
|
checked: accessTypeSelector.currentIndex === 1
|
2023-06-13 20:03:20 +09:00
|
|
|
|
|
|
|
|
implicitWidth: (root.width - 32) / 2
|
2023-11-21 20:13:51 +07:00
|
|
|
text: qsTr("Users")
|
2023-06-13 20:03:20 +09:00
|
|
|
|
|
|
|
|
onClicked: {
|
|
|
|
|
accessTypeSelector.currentIndex = 1
|
2023-11-21 20:13:51 +07:00
|
|
|
PageController.showBusyIndicator(true)
|
2026-05-28 10:57:08 +08:00
|
|
|
ExportController.updateClientManagementModel(ServersUiController.processedServerId,
|
2026-04-30 14:53:03 +08:00
|
|
|
ServersUiController.processedContainerIndex)
|
2023-11-21 20:13:51 +07:00
|
|
|
PageController.showBusyIndicator(false)
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
2025-08-01 05:56:02 +02:00
|
|
|
|
|
|
|
|
Keys.onEnterPressed: this.clicked()
|
|
|
|
|
Keys.onReturnPressed: this.clicked()
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ParagraphTextType {
|
|
|
|
|
Layout.fillWidth: true
|
2023-06-20 10:25:24 +09:00
|
|
|
Layout.topMargin: 24
|
2023-08-26 10:08:50 +03:00
|
|
|
Layout.bottomMargin: 24
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-11-21 20:13:51 +07:00
|
|
|
visible: accessTypeSelector.currentIndex === 0
|
|
|
|
|
|
|
|
|
|
text: qsTr("Share VPN access without the ability to manage the server")
|
2024-08-20 16:54:05 +07:00
|
|
|
color: AmneziaStyle.color.mutedGray
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
|
2023-11-21 20:13:51 +07:00
|
|
|
TextFieldWithHeaderType {
|
2023-11-23 00:03:43 +07:00
|
|
|
id: clientNameTextField
|
2023-11-21 20:13:51 +07:00
|
|
|
Layout.fillWidth: true
|
|
|
|
|
Layout.topMargin: 16
|
|
|
|
|
|
|
|
|
|
visible: accessTypeSelector.currentIndex === 0
|
|
|
|
|
|
|
|
|
|
headerText: qsTr("User name")
|
2025-01-24 23:27:01 +07:00
|
|
|
textField.text: "New client"
|
2023-12-12 17:15:10 +03:00
|
|
|
textField.maximumLength: 20
|
2023-11-21 20:13:51 +07:00
|
|
|
|
|
|
|
|
checkEmptyText: true
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-13 20:03:20 +09:00
|
|
|
DropDownType {
|
|
|
|
|
id: serverSelector
|
|
|
|
|
|
2025-11-26 06:07:24 +02:00
|
|
|
signal serverSelectorIndexChanged
|
2023-11-26 21:15:58 +07:00
|
|
|
property int currentIndex: -1
|
2023-09-17 15:01:31 +05:00
|
|
|
|
2023-06-13 20:03:20 +09:00
|
|
|
Layout.fillWidth: true
|
2023-08-26 10:08:50 +03:00
|
|
|
Layout.topMargin: 16
|
2023-06-13 20:03:20 +09:00
|
|
|
|
|
|
|
|
drawerHeight: 0.4375
|
2024-02-16 15:24:06 +05:00
|
|
|
drawerParent: root
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-10-09 22:39:32 +05:00
|
|
|
descriptionText: qsTr("Server")
|
2023-06-13 20:03:20 +09:00
|
|
|
headerText: qsTr("Server")
|
|
|
|
|
|
2023-09-17 15:01:31 +05:00
|
|
|
listView: ListViewWithRadioButtonType {
|
|
|
|
|
id: serverSelectorListView
|
|
|
|
|
rootWidth: root.width
|
|
|
|
|
imageSource: "qrc:/images/controls/check.svg"
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-06-23 15:24:40 +09:00
|
|
|
model: SortFilterProxyModel {
|
|
|
|
|
id: proxyServersModel
|
|
|
|
|
sourceModel: ServersModel
|
|
|
|
|
filters: [
|
|
|
|
|
ValueFilter {
|
|
|
|
|
roleName: "hasWriteAccess"
|
|
|
|
|
value: true
|
2024-02-29 17:22:17 +07:00
|
|
|
},
|
|
|
|
|
ValueFilter {
|
|
|
|
|
roleName: "hasInstalledContainers"
|
|
|
|
|
value: true
|
2023-06-23 15:24:40 +09:00
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-13 20:03:20 +09:00
|
|
|
clickedFunction: function() {
|
2023-07-24 16:31:04 +09:00
|
|
|
handler()
|
|
|
|
|
|
2024-12-31 04:16:52 +01:00
|
|
|
if (serverSelector.currentIndex !== serverSelectorListView.selectedIndex) {
|
|
|
|
|
serverSelector.currentIndex = serverSelectorListView.selectedIndex
|
2025-11-26 06:07:24 +02:00
|
|
|
serverSelector.serverSelectorIndexChanged()
|
2023-09-17 15:01:31 +05:00
|
|
|
}
|
|
|
|
|
|
2024-12-31 04:16:52 +01:00
|
|
|
serverSelector.closeTriggered()
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Component.onCompleted: {
|
2026-05-28 10:57:08 +08:00
|
|
|
if (ServersUiController.isServerHasWriteAccess(ServersUiController.defaultServerId)
|
|
|
|
|
&& ServersUiController.serverHasInstalledContainers(ServersUiController.defaultServerId)) {
|
|
|
|
|
serverSelectorListView.selectedIndex =
|
|
|
|
|
proxyServersModel.mapFromSource(ServersUiController.getServerIndexById(ServersUiController.defaultServerId))
|
2024-02-29 17:22:17 +07:00
|
|
|
} else {
|
2024-12-31 04:16:52 +01:00
|
|
|
serverSelectorListView.selectedIndex = 0
|
2024-02-29 17:22:17 +07:00
|
|
|
}
|
|
|
|
|
|
2025-01-08 09:12:55 +03:00
|
|
|
serverSelectorListView.positionViewAtIndex(selectedIndex, ListView.Beginning)
|
2023-11-26 21:15:58 +07:00
|
|
|
serverSelectorListView.triggerCurrentItem()
|
2023-07-24 16:31:04 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handler() {
|
2023-06-13 20:03:20 +09:00
|
|
|
serverSelector.text = selectedText
|
2026-05-28 10:57:08 +08:00
|
|
|
ServersUiController.setProcessedServerId(ServersUiController.getServerId(proxyServersModel.mapToSource(selectedIndex)))
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
}
|
2023-09-17 15:01:31 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DropDownType {
|
2026-04-30 14:53:03 +08:00
|
|
|
id: containerSelector
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
signal containerSelectorTextChanged
|
2025-11-26 06:07:24 +02:00
|
|
|
|
2023-09-17 15:01:31 +05:00
|
|
|
Layout.fillWidth: true
|
|
|
|
|
Layout.topMargin: 16
|
|
|
|
|
|
|
|
|
|
drawerHeight: 0.5
|
2024-02-16 15:24:06 +05:00
|
|
|
drawerParent: root
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-10-03 23:28:44 +05:00
|
|
|
descriptionText: qsTr("Protocol")
|
2023-09-17 15:01:31 +05:00
|
|
|
headerText: qsTr("Protocol")
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-09-17 15:01:31 +05:00
|
|
|
listView: ListViewWithRadioButtonType {
|
2026-04-30 14:53:03 +08:00
|
|
|
id: containerSelectorListView
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-09-17 15:01:31 +05:00
|
|
|
rootWidth: root.width
|
|
|
|
|
imageSource: "qrc:/images/controls/check.svg"
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-09-17 15:01:31 +05:00
|
|
|
model: SortFilterProxyModel {
|
|
|
|
|
id: proxyContainersModel
|
|
|
|
|
sourceModel: ContainersModel
|
|
|
|
|
filters: [
|
|
|
|
|
ValueFilter {
|
|
|
|
|
roleName: "isInstalled"
|
|
|
|
|
value: true
|
|
|
|
|
},
|
|
|
|
|
ValueFilter {
|
|
|
|
|
roleName: "isShareable"
|
|
|
|
|
value: true
|
2026-06-04 15:45:53 +01:00
|
|
|
},
|
|
|
|
|
ValueFilter {
|
|
|
|
|
roleName: "isUnsupportedContainer"
|
|
|
|
|
value: false
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
2023-09-17 15:01:31 +05:00
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clickedFunction: function() {
|
|
|
|
|
handler()
|
|
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
containerSelector.closeTriggered()
|
2023-09-17 15:01:31 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Connections {
|
|
|
|
|
target: serverSelector
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2025-11-26 06:07:24 +02:00
|
|
|
function onServerSelectorIndexChanged() {
|
2026-06-04 15:45:53 +01:00
|
|
|
if (!proxyContainersModel.count) {
|
|
|
|
|
root.shareButtonEnabled = false
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var defaultContainer = proxyContainersModel.mapFromSource(
|
|
|
|
|
ServersUiController.serverDefaultContainer(ServersUiController.processedServerId))
|
|
|
|
|
if (defaultContainer < 0) {
|
|
|
|
|
defaultContainer = 0
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
containerSelectorListView.selectedIndex = defaultContainer
|
2026-06-04 15:45:53 +01:00
|
|
|
containerSelectorListView.positionViewAtIndex(defaultContainer, ListView.Beginning)
|
2026-04-30 14:53:03 +08:00
|
|
|
containerSelectorListView.triggerCurrentItem()
|
2023-09-17 15:01:31 +05:00
|
|
|
}
|
|
|
|
|
}
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-09-17 15:01:31 +05:00
|
|
|
function handler() {
|
|
|
|
|
if (!proxyContainersModel.count) {
|
|
|
|
|
root.shareButtonEnabled = false
|
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
root.shareButtonEnabled = true
|
|
|
|
|
}
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
containerSelector.text = selectedText
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
ServersUiController.processedContainerIndex = proxyContainersModel.mapToSource(selectedIndex)
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-11-23 14:32:16 +07:00
|
|
|
fillConnectionTypeModel()
|
|
|
|
|
|
|
|
|
|
if (accessTypeSelector.currentIndex === 1) {
|
2023-11-21 20:13:51 +07:00
|
|
|
PageController.showBusyIndicator(true)
|
2026-05-28 10:57:08 +08:00
|
|
|
ExportController.updateClientManagementModel(ServersUiController.processedServerId,
|
2026-04-30 14:53:03 +08:00
|
|
|
ServersUiController.processedContainerIndex)
|
2023-11-21 20:13:51 +07:00
|
|
|
PageController.showBusyIndicator(false)
|
|
|
|
|
}
|
2025-11-26 06:07:24 +02:00
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
containerSelector.containerSelectorTextChanged()
|
2023-09-17 15:01:31 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function fillConnectionTypeModel() {
|
|
|
|
|
root.connectionTypesModel = [amneziaConnectionFormat]
|
|
|
|
|
|
2024-12-31 04:16:52 +01:00
|
|
|
var index = proxyContainersModel.mapToSource(selectedIndex)
|
2023-09-17 15:01:31 +05:00
|
|
|
|
|
|
|
|
if (index === ContainerProps.containerFromString("amnezia-openvpn")) {
|
|
|
|
|
root.connectionTypesModel.push(openVpnConnectionFormat)
|
|
|
|
|
} else if (index === ContainerProps.containerFromString("amnezia-wireguard")) {
|
|
|
|
|
root.connectionTypesModel.push(wireGuardConnectionFormat)
|
2024-02-23 19:55:59 +02:00
|
|
|
} else if (index === ContainerProps.containerFromString("amnezia-awg")) {
|
|
|
|
|
root.connectionTypesModel.push(awgConnectionFormat)
|
2025-12-11 15:18:36 +08:00
|
|
|
} else if (index === ContainerProps.containerFromString("amnezia-awg2")) {
|
|
|
|
|
root.connectionTypesModel.push(awgConnectionFormat)
|
2024-03-27 11:02:34 +00:00
|
|
|
} else if (index === ContainerProps.containerFromString("amnezia-xray")) {
|
|
|
|
|
root.connectionTypesModel.push(xrayConnectionFormat)
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DropDownType {
|
2023-06-23 15:24:40 +09:00
|
|
|
id: exportTypeSelector
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-08-16 12:11:34 +05:00
|
|
|
property int currentIndex: 0
|
2023-06-13 20:03:20 +09:00
|
|
|
|
|
|
|
|
Layout.fillWidth: true
|
|
|
|
|
Layout.topMargin: 16
|
|
|
|
|
|
|
|
|
|
drawerHeight: 0.4375
|
2024-02-16 15:24:06 +05:00
|
|
|
drawerParent: root
|
2023-06-13 20:03:20 +09:00
|
|
|
|
|
|
|
|
visible: accessTypeSelector.currentIndex === 0
|
2023-06-27 19:07:42 +09:00
|
|
|
enabled: root.connectionTypesModel.length > 1
|
2023-06-13 20:03:20 +09:00
|
|
|
|
|
|
|
|
descriptionText: qsTr("Connection format")
|
|
|
|
|
headerText: qsTr("Connection format")
|
|
|
|
|
|
2023-08-16 22:45:05 +05:00
|
|
|
listView: ListViewWithRadioButtonType {
|
2025-01-15 12:04:48 +07:00
|
|
|
id: exportTypeSelectorListView
|
|
|
|
|
|
2023-08-19 13:12:54 +05:00
|
|
|
onCurrentIndexChanged: {
|
2025-01-15 12:04:48 +07:00
|
|
|
exportTypeSelector.currentIndex = exportTypeSelectorListView.selectedIndex
|
|
|
|
|
exportTypeSelector.text = exportTypeSelectorListView.selectedText
|
2023-08-19 13:12:54 +05:00
|
|
|
}
|
2023-08-16 12:11:34 +05:00
|
|
|
|
2025-11-26 06:07:24 +02:00
|
|
|
onModelChanged: {
|
|
|
|
|
if (exportTypeSelector.currentIndex >= model.length || exportTypeSelector.currentIndex < 0) {
|
|
|
|
|
exportTypeSelector.currentIndex = 0
|
|
|
|
|
}
|
|
|
|
|
selectedIndex = exportTypeSelector.currentIndex
|
2026-02-26 18:31:18 +04:00
|
|
|
if (model.length > 0 && model[selectedIndex] && model[selectedIndex].name !== undefined) {
|
|
|
|
|
exportTypeSelectorListView.selectedText = model[selectedIndex].name
|
|
|
|
|
exportTypeSelector.text = model[selectedIndex].name
|
|
|
|
|
} else {
|
|
|
|
|
exportTypeSelectorListView.selectedText = ""
|
|
|
|
|
exportTypeSelector.text = ""
|
|
|
|
|
}
|
2025-11-26 06:07:24 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-13 20:03:20 +09:00
|
|
|
rootWidth: root.width
|
|
|
|
|
|
2023-08-19 13:12:54 +05:00
|
|
|
imageSource: "qrc:/images/controls/check.svg"
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-06-27 19:07:42 +09:00
|
|
|
model: root.connectionTypesModel
|
2023-08-19 13:12:54 +05:00
|
|
|
currentIndex: 0
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2025-11-26 06:07:24 +02:00
|
|
|
Connections {
|
2026-04-30 14:53:03 +08:00
|
|
|
target: containerSelector
|
2025-11-26 06:07:24 +02:00
|
|
|
|
2026-04-30 14:53:03 +08:00
|
|
|
function onContainerSelectorTextChanged() {
|
2025-11-26 06:07:24 +02:00
|
|
|
if (exportTypeSelector.currentIndex >= root.connectionTypesModel.length) {
|
|
|
|
|
exportTypeSelectorListView.selectedIndex = 0
|
|
|
|
|
exportTypeSelector.currentIndex = 0
|
|
|
|
|
exportTypeSelector.text = root.connectionTypesModel[0].name
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
|
2025-11-26 06:07:24 +02:00
|
|
|
clickedFunction: function() {
|
2025-01-15 12:04:48 +07:00
|
|
|
exportTypeSelector.text = exportTypeSelectorListView.selectedText
|
|
|
|
|
exportTypeSelector.currentIndex = exportTypeSelectorListView.selectedIndex
|
2025-11-26 06:07:24 +02:00
|
|
|
exportTypeSelector.closeTriggered()
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BasicButtonType {
|
2024-02-17 23:09:05 +02:00
|
|
|
id: shareButton
|
|
|
|
|
|
2023-06-13 20:03:20 +09:00
|
|
|
Layout.fillWidth: true
|
2023-08-26 10:08:50 +03:00
|
|
|
Layout.topMargin: 40
|
2024-02-29 17:22:17 +07:00
|
|
|
Layout.bottomMargin: 32
|
2023-06-13 20:03:20 +09:00
|
|
|
|
2023-07-13 11:29:26 +09:00
|
|
|
enabled: shareButtonEnabled
|
2023-11-21 20:13:51 +07:00
|
|
|
visible: accessTypeSelector.currentIndex === 0
|
2023-07-13 11:29:26 +09:00
|
|
|
|
2023-06-13 20:03:20 +09:00
|
|
|
text: qsTr("Share")
|
2024-11-12 10:22:34 +04:00
|
|
|
leftImageSource: "qrc:/images/controls/share-2.svg"
|
2024-04-18 17:54:55 +04:00
|
|
|
|
2024-02-17 23:09:05 +02:00
|
|
|
clickedFunc: function(){
|
2025-01-24 23:27:01 +07:00
|
|
|
if (clientNameTextField.textField.text !== "") {
|
2023-12-12 17:15:10 +03:00
|
|
|
ExportController.generateConfig(root.connectionTypesModel[exportTypeSelector.currentIndex].type)
|
|
|
|
|
}
|
2023-11-21 20:13:51 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Header2Type {
|
2024-04-18 17:54:55 +04:00
|
|
|
id: usersHeader
|
2023-11-21 20:13:51 +07:00
|
|
|
Layout.fillWidth: true
|
|
|
|
|
Layout.topMargin: 24
|
|
|
|
|
Layout.bottomMargin: 16
|
|
|
|
|
|
2023-11-23 14:32:16 +07:00
|
|
|
visible: accessTypeSelector.currentIndex === 1 && !root.isSearchBarVisible
|
2023-11-21 20:13:51 +07:00
|
|
|
|
|
|
|
|
headerText: qsTr("Users")
|
2023-11-23 14:32:16 +07:00
|
|
|
actionButtonImage: "qrc:/images/controls/search.svg"
|
|
|
|
|
actionButtonFunction: function() {
|
|
|
|
|
root.isSearchBarVisible = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RowLayout {
|
|
|
|
|
Layout.topMargin: 24
|
|
|
|
|
Layout.bottomMargin: 16
|
|
|
|
|
visible: accessTypeSelector.currentIndex === 1 && root.isSearchBarVisible
|
|
|
|
|
|
|
|
|
|
TextFieldWithHeaderType {
|
|
|
|
|
id: searchTextField
|
|
|
|
|
Layout.fillWidth: true
|
|
|
|
|
|
2025-01-24 23:27:01 +07:00
|
|
|
textField.placeholderText: qsTr("Search")
|
2024-04-18 17:54:55 +04:00
|
|
|
|
|
|
|
|
Keys.onEscapePressed: {
|
2025-11-26 05:57:28 +02:00
|
|
|
searchTextField.textField.text = ""
|
2024-04-18 17:54:55 +04:00
|
|
|
root.isSearchBarVisible = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function navigateTo() {
|
2025-01-24 23:27:01 +07:00
|
|
|
if (searchTextField.textField.text === "") {
|
2024-04-18 17:54:55 +04:00
|
|
|
root.isSearchBarVisible = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Keys.onTabPressed: { navigateTo() }
|
|
|
|
|
Keys.onEnterPressed: { navigateTo() }
|
|
|
|
|
Keys.onReturnPressed: { navigateTo() }
|
2023-11-23 14:32:16 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImageButtonType {
|
2024-04-18 17:54:55 +04:00
|
|
|
id: closeSearchButton
|
2023-11-23 14:32:16 +07:00
|
|
|
image: "qrc:/images/controls/close.svg"
|
2024-08-20 16:54:05 +07:00
|
|
|
imageColor: AmneziaStyle.color.paleGray
|
2023-11-23 14:32:16 +07:00
|
|
|
|
2024-04-18 17:54:55 +04:00
|
|
|
function clickedFunc() {
|
2025-11-26 05:57:28 +02:00
|
|
|
searchTextField.textField.text = ""
|
2023-11-23 14:32:16 +07:00
|
|
|
root.isSearchBarVisible = false
|
|
|
|
|
}
|
2024-04-18 17:54:55 +04:00
|
|
|
|
|
|
|
|
onClicked: clickedFunc()
|
|
|
|
|
Keys.onEnterPressed: clickedFunc()
|
|
|
|
|
Keys.onReturnPressed: clickedFunc()
|
2023-11-23 14:32:16 +07:00
|
|
|
}
|
2023-11-21 20:13:51 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ListView {
|
2023-11-23 00:03:43 +07:00
|
|
|
id: clientsListView
|
2023-11-21 20:13:51 +07:00
|
|
|
Layout.fillWidth: true
|
|
|
|
|
Layout.preferredHeight: childrenRect.height
|
|
|
|
|
|
|
|
|
|
visible: accessTypeSelector.currentIndex === 1
|
|
|
|
|
|
2025-11-26 06:07:24 +02:00
|
|
|
function escapeRe(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') }
|
|
|
|
|
|
2024-12-31 04:16:52 +01:00
|
|
|
property bool isFocusable: true
|
2025-09-29 05:51:52 +03:00
|
|
|
property bool freezeFilter: false
|
2024-12-31 04:16:52 +01:00
|
|
|
|
2023-11-23 14:32:16 +07:00
|
|
|
model: SortFilterProxyModel {
|
|
|
|
|
id: proxyClientManagementModel
|
|
|
|
|
sourceModel: ClientManagementModel
|
|
|
|
|
filters: RegExpFilter {
|
|
|
|
|
roleName: "clientName"
|
2025-09-29 05:51:52 +03:00
|
|
|
enabled: !clientsListView.freezeFilter
|
2025-11-26 06:07:24 +02:00
|
|
|
pattern: ".*" + clientsListView.escapeRe(searchTextField.textField.text) + ".*"
|
2023-11-23 14:32:16 +07:00
|
|
|
caseSensitivity: Qt.CaseInsensitive
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-21 20:13:51 +07:00
|
|
|
|
|
|
|
|
clip: true
|
2025-01-08 09:12:55 +03:00
|
|
|
interactive: false
|
2024-12-31 04:16:52 +01:00
|
|
|
reuseItems: true
|
2024-04-18 17:54:55 +04:00
|
|
|
|
2023-11-21 20:13:51 +07:00
|
|
|
delegate: Item {
|
2023-11-23 00:03:43 +07:00
|
|
|
implicitWidth: clientsListView.width
|
2023-11-21 20:13:51 +07:00
|
|
|
implicitHeight: delegateContent.implicitHeight
|
|
|
|
|
|
|
|
|
|
ColumnLayout {
|
|
|
|
|
id: delegateContent
|
|
|
|
|
|
|
|
|
|
anchors.top: parent.top
|
|
|
|
|
anchors.left: parent.left
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
|
|
|
|
|
|
anchors.rightMargin: -16
|
|
|
|
|
anchors.leftMargin: -16
|
|
|
|
|
|
|
|
|
|
LabelWithButtonType {
|
2024-04-18 17:54:55 +04:00
|
|
|
id: clientFocusItem
|
2023-11-21 20:13:51 +07:00
|
|
|
Layout.fillWidth: true
|
|
|
|
|
|
2023-11-23 00:03:43 +07:00
|
|
|
text: clientName
|
2023-11-21 20:13:51 +07:00
|
|
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
|
|
|
|
|
|
|
|
|
clickedFunction: function() {
|
2024-12-31 04:16:52 +01:00
|
|
|
clientInfoDrawer.openTriggered()
|
2023-11-21 20:13:51 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DividerType {}
|
|
|
|
|
|
2024-02-16 15:24:06 +05:00
|
|
|
DrawerType2 {
|
2023-11-23 00:03:43 +07:00
|
|
|
id: clientInfoDrawer
|
2023-11-21 20:13:51 +07:00
|
|
|
|
2024-02-16 15:24:06 +05:00
|
|
|
parent: root
|
|
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
width: root.width
|
|
|
|
|
height: root.height
|
2023-11-21 20:13:51 +07:00
|
|
|
|
2024-12-31 04:16:52 +01:00
|
|
|
expandedStateContent: ColumnLayout {
|
|
|
|
|
id: expandedStateContent
|
2023-11-21 20:13:51 +07:00
|
|
|
anchors.top: parent.top
|
|
|
|
|
anchors.left: parent.left
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
|
anchors.topMargin: 16
|
|
|
|
|
anchors.leftMargin: 16
|
|
|
|
|
anchors.rightMargin: 16
|
|
|
|
|
|
2024-04-28 16:03:41 +03:00
|
|
|
onImplicitHeightChanged: {
|
2024-12-31 04:16:52 +01:00
|
|
|
clientInfoDrawer.expandedHeight = expandedStateContent.implicitHeight + 32
|
2024-04-18 17:54:55 +04:00
|
|
|
}
|
|
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
Header2TextType {
|
|
|
|
|
Layout.maximumWidth: parent.width
|
|
|
|
|
Layout.bottomMargin: 24
|
2023-11-21 20:13:51 +07:00
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
text: clientName
|
|
|
|
|
maximumLineCount: 2
|
|
|
|
|
wrapMode: Text.Wrap
|
|
|
|
|
elide: Qt.ElideRight
|
2024-04-28 16:03:41 +03:00
|
|
|
}
|
|
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
ParagraphTextType {
|
|
|
|
|
color: AmneziaStyle.color.mutedGray
|
|
|
|
|
visible: creationDate
|
2025-01-08 09:12:55 +03:00
|
|
|
Layout.maximumWidth: parent.width
|
|
|
|
|
|
|
|
|
|
maximumLineCount: 2
|
|
|
|
|
wrapMode: Text.Wrap
|
|
|
|
|
elide: Qt.ElideRight
|
2024-04-28 16:03:41 +03:00
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
text: qsTr("Creation date: %1").arg(creationDate)
|
|
|
|
|
}
|
2024-04-28 16:03:41 +03:00
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
ParagraphTextType {
|
|
|
|
|
color: AmneziaStyle.color.mutedGray
|
|
|
|
|
visible: latestHandshake
|
2025-01-08 09:12:55 +03:00
|
|
|
Layout.maximumWidth: parent.width
|
|
|
|
|
|
|
|
|
|
maximumLineCount: 2
|
|
|
|
|
wrapMode: Text.Wrap
|
|
|
|
|
elide: Qt.ElideRight
|
2024-04-28 16:03:41 +03:00
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
text: qsTr("Latest handshake: %1").arg(latestHandshake)
|
|
|
|
|
}
|
2024-04-28 16:03:41 +03:00
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
ParagraphTextType {
|
|
|
|
|
color: AmneziaStyle.color.mutedGray
|
|
|
|
|
visible: dataReceived
|
2025-01-08 09:12:55 +03:00
|
|
|
Layout.maximumWidth: parent.width
|
|
|
|
|
|
|
|
|
|
maximumLineCount: 2
|
|
|
|
|
wrapMode: Text.Wrap
|
|
|
|
|
elide: Qt.ElideRight
|
2024-04-28 16:03:41 +03:00
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
text: qsTr("Data received: %1").arg(dataReceived)
|
|
|
|
|
}
|
2024-04-28 16:03:41 +03:00
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
ParagraphTextType {
|
|
|
|
|
color: AmneziaStyle.color.mutedGray
|
|
|
|
|
visible: dataSent
|
2025-01-08 09:12:55 +03:00
|
|
|
Layout.maximumWidth: parent.width
|
|
|
|
|
|
|
|
|
|
maximumLineCount: 2
|
|
|
|
|
wrapMode: Text.Wrap
|
|
|
|
|
elide: Qt.ElideRight
|
2024-04-28 16:03:41 +03:00
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
text: qsTr("Data sent: %1").arg(dataSent)
|
|
|
|
|
}
|
2024-09-17 08:28:44 +02:00
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
ParagraphTextType {
|
|
|
|
|
color: AmneziaStyle.color.mutedGray
|
|
|
|
|
visible: allowedIps
|
2025-01-08 09:12:55 +03:00
|
|
|
Layout.maximumWidth: parent.width
|
|
|
|
|
|
|
|
|
|
wrapMode: Text.Wrap
|
2024-09-17 08:28:44 +02:00
|
|
|
|
2024-10-24 14:05:26 +08:00
|
|
|
text: qsTr("Allowed IPs: %1").arg(allowedIps)
|
2023-11-21 20:13:51 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BasicButtonType {
|
2024-04-18 17:54:55 +04:00
|
|
|
id: renameButton
|
2023-11-21 20:13:51 +07:00
|
|
|
Layout.fillWidth: true
|
|
|
|
|
Layout.topMargin: 24
|
|
|
|
|
|
2024-07-07 13:42:38 +03:00
|
|
|
defaultColor: AmneziaStyle.color.transparent
|
2024-08-20 16:54:05 +07:00
|
|
|
hoveredColor: AmneziaStyle.color.translucentWhite
|
|
|
|
|
pressedColor: AmneziaStyle.color.sheerWhite
|
|
|
|
|
disabledColor: AmneziaStyle.color.mutedGray
|
|
|
|
|
textColor: AmneziaStyle.color.paleGray
|
2023-11-21 20:13:51 +07:00
|
|
|
borderWidth: 1
|
|
|
|
|
|
|
|
|
|
text: qsTr("Rename")
|
|
|
|
|
|
2024-02-17 23:09:05 +02:00
|
|
|
clickedFunc: function() {
|
2024-12-31 04:16:52 +01:00
|
|
|
clientNameEditDrawer.openTriggered()
|
2023-11-21 20:13:51 +07:00
|
|
|
}
|
|
|
|
|
|
2024-02-16 15:24:06 +05:00
|
|
|
DrawerType2 {
|
2023-11-21 20:13:51 +07:00
|
|
|
id: clientNameEditDrawer
|
|
|
|
|
|
2024-02-16 15:24:06 +05:00
|
|
|
parent: root
|
2023-11-21 20:13:51 +07:00
|
|
|
|
2024-02-16 15:24:06 +05:00
|
|
|
anchors.fill: parent
|
|
|
|
|
expandedHeight: root.height * 0.35
|
2023-11-21 20:13:51 +07:00
|
|
|
|
2024-12-31 04:16:52 +01:00
|
|
|
expandedStateContent: ColumnLayout {
|
2023-11-21 20:13:51 +07:00
|
|
|
anchors.top: parent.top
|
|
|
|
|
anchors.left: parent.left
|
|
|
|
|
anchors.right: parent.right
|
2024-02-16 15:24:06 +05:00
|
|
|
anchors.topMargin: 32
|
2023-11-21 20:13:51 +07:00
|
|
|
anchors.leftMargin: 16
|
|
|
|
|
anchors.rightMargin: 16
|
|
|
|
|
|
|
|
|
|
TextFieldWithHeaderType {
|
2023-11-23 00:03:43 +07:00
|
|
|
id: clientNameEditor
|
2023-11-21 20:13:51 +07:00
|
|
|
Layout.fillWidth: true
|
|
|
|
|
headerText: qsTr("Client name")
|
2025-01-24 23:27:01 +07:00
|
|
|
textField.text: clientName
|
2023-12-12 17:15:10 +03:00
|
|
|
textField.maximumLength: 20
|
|
|
|
|
checkEmptyText: true
|
2023-11-21 20:13:51 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BasicButtonType {
|
2024-02-17 23:09:05 +02:00
|
|
|
id: saveButton
|
|
|
|
|
|
2023-11-21 20:13:51 +07:00
|
|
|
Layout.fillWidth: true
|
|
|
|
|
|
|
|
|
|
text: qsTr("Save")
|
|
|
|
|
|
2024-02-17 23:09:05 +02:00
|
|
|
clickedFunc: function() {
|
2025-01-24 23:27:01 +07:00
|
|
|
if (clientNameEditor.textField.text === "") {
|
2023-12-12 17:15:10 +03:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-24 23:27:01 +07:00
|
|
|
if (clientNameEditor.textField.text !== clientName) {
|
2025-09-29 05:51:52 +03:00
|
|
|
clientsListView.freezeFilter = true
|
2023-11-21 20:13:51 +07:00
|
|
|
PageController.showBusyIndicator(true)
|
2025-09-03 06:56:08 +03:00
|
|
|
ExportController.renameClient(proxyClientManagementModel.mapToSource(index),
|
2026-05-15 12:33:36 +08:00
|
|
|
clientNameEditor.textField.text,
|
2026-05-28 10:57:08 +08:00
|
|
|
ServersUiController.processedServerId,
|
2026-05-15 12:33:36 +08:00
|
|
|
ServersUiController.processedContainerIndex)
|
2023-11-21 20:13:51 +07:00
|
|
|
PageController.showBusyIndicator(false)
|
2025-09-29 05:51:52 +03:00
|
|
|
Qt.callLater(function(){ clientsListView.freezeFilter = false })
|
2024-12-31 04:16:52 +01:00
|
|
|
clientNameEditDrawer.closeTriggered()
|
2023-11-21 20:13:51 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BasicButtonType {
|
2024-04-18 17:54:55 +04:00
|
|
|
id: revokeButton
|
2023-11-21 20:13:51 +07:00
|
|
|
Layout.fillWidth: true
|
2024-10-24 14:05:26 +08:00
|
|
|
Layout.topMargin: 8
|
2023-11-21 20:13:51 +07:00
|
|
|
|
2024-07-07 13:42:38 +03:00
|
|
|
defaultColor: AmneziaStyle.color.transparent
|
2024-08-20 16:54:05 +07:00
|
|
|
hoveredColor: AmneziaStyle.color.translucentWhite
|
|
|
|
|
pressedColor: AmneziaStyle.color.sheerWhite
|
|
|
|
|
disabledColor: AmneziaStyle.color.mutedGray
|
|
|
|
|
textColor: AmneziaStyle.color.paleGray
|
2023-11-21 20:13:51 +07:00
|
|
|
borderWidth: 1
|
|
|
|
|
|
|
|
|
|
text: qsTr("Revoke")
|
|
|
|
|
|
2024-02-17 23:09:05 +02:00
|
|
|
clickedFunc: function() {
|
2024-02-16 15:24:06 +05:00
|
|
|
var headerText = qsTr("Revoke the config for a user - %1?").arg(clientName)
|
|
|
|
|
var descriptionText = qsTr("The user will no longer be able to connect to your server.")
|
|
|
|
|
var yesButtonText = qsTr("Continue")
|
|
|
|
|
var noButtonText = qsTr("Cancel")
|
2023-11-21 20:13:51 +07:00
|
|
|
|
2024-02-16 15:24:06 +05:00
|
|
|
var yesButtonFunction = function() {
|
2024-12-31 04:16:52 +01:00
|
|
|
clientInfoDrawer.closeTriggered()
|
2025-09-03 06:56:08 +03:00
|
|
|
PageController.showBusyIndicator(true)
|
|
|
|
|
ExportController.revokeConfig(proxyClientManagementModel.mapToSource(index),
|
2026-05-28 10:57:08 +08:00
|
|
|
ServersUiController.processedServerId,
|
2026-05-15 12:33:36 +08:00
|
|
|
ServersUiController.processedContainerIndex)
|
2023-11-21 20:13:51 +07:00
|
|
|
}
|
2024-02-16 15:24:06 +05:00
|
|
|
var noButtonFunction = function() {
|
2023-11-21 20:13:51 +07:00
|
|
|
}
|
2024-02-16 15:24:06 +05:00
|
|
|
|
2026-06-04 15:45:53 +01:00
|
|
|
if (ConnectionController.isRevokeBlockedDuringActiveConnection(
|
|
|
|
|
ServersUiController.processedServerId,
|
|
|
|
|
ServersUiController.processedContainerIndex,
|
|
|
|
|
clientId)) {
|
2026-05-15 16:01:39 +03:00
|
|
|
PageController.showNotificationMessage("Unable to revoke current config during active connection")
|
|
|
|
|
} else {
|
|
|
|
|
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
|
|
|
|
}
|
2023-11-21 20:13:51 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-06-13 20:03:20 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-02-16 15:24:06 +05:00
|
|
|
|
2023-05-06 06:52:23 +03:00
|
|
|
}
|