diff --git a/client/images/controls/close.svg b/client/images/controls/close.svg
new file mode 100644
index 00000000..0643cdc8
--- /dev/null
+++ b/client/images/controls/close.svg
@@ -0,0 +1,6 @@
+
diff --git a/client/images/controls/search.svg b/client/images/controls/search.svg
new file mode 100644
index 00000000..56fa50e1
--- /dev/null
+++ b/client/images/controls/search.svg
@@ -0,0 +1,6 @@
+
diff --git a/client/resources.qrc b/client/resources.qrc
index 1baf993b..dfadcb20 100644
--- a/client/resources.qrc
+++ b/client/resources.qrc
@@ -223,5 +223,7 @@
server_scripts/awg/run_container.sh
server_scripts/awg/Dockerfile
ui/qml/Pages2/PageShareFullAccess.qml
+ images/controls/close.svg
+ images/controls/search.svg
diff --git a/client/ui/controllers/exportController.cpp b/client/ui/controllers/exportController.cpp
index a8be624d..e3719e50 100644
--- a/client/ui/controllers/exportController.cpp
+++ b/client/ui/controllers/exportController.cpp
@@ -232,6 +232,14 @@ void ExportController::exportConfig(const QString &fileName)
SystemController::saveFile(fileName, m_config);
}
+void ExportController::updateClientManagementModel(const DockerContainer container, ServerCredentials credentials)
+{
+ ErrorCode errorCode = m_clientManagementModel->updateModel(container, credentials);
+ if (errorCode != ErrorCode::NoError) {
+ emit exportErrorOccurred(errorString(errorCode));
+ }
+}
+
void ExportController::revokeConfig(const int row, const DockerContainer container, ServerCredentials credentials)
{
ErrorCode errorCode = m_clientManagementModel->revokeClient(row, container, credentials);
diff --git a/client/ui/controllers/exportController.h b/client/ui/controllers/exportController.h
index b34a05bc..56db9da0 100644
--- a/client/ui/controllers/exportController.h
+++ b/client/ui/controllers/exportController.h
@@ -39,6 +39,7 @@ public slots:
void exportConfig(const QString &fileName);
+ void updateClientManagementModel(const DockerContainer container, ServerCredentials credentials);
void revokeConfig(const int row, const DockerContainer container, ServerCredentials credentials);
void renameClient(const int row, const QString &clientName, const DockerContainer container, ServerCredentials credentials);
diff --git a/client/ui/models/clientManagementModel.cpp b/client/ui/models/clientManagementModel.cpp
index f53794d5..bfc33eb9 100644
--- a/client/ui/models/clientManagementModel.cpp
+++ b/client/ui/models/clientManagementModel.cpp
@@ -40,9 +40,6 @@ QVariant ClientManagementModel::data(const QModelIndex &index, int role) const
switch (role) {
case ClientNameRole: return userData.value(configKey::clientName).toString();
- case ContainerNameRole:
- return ContainerProps::containerHumanNames().value(
- static_cast(userData.value(configKey::container).toInt()));
}
return QVariant();
@@ -50,6 +47,9 @@ QVariant ClientManagementModel::data(const QModelIndex &index, int role) const
ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCredentials credentials)
{
+ beginResetModel();
+ m_clientsTable = QJsonArray();
+
ServerController serverController(m_settings);
ErrorCode error = ErrorCode::NoError;
@@ -60,10 +60,10 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
serverController.getTextFileFromContainer(container, credentials, clientsTableFile, &error);
if (error != ErrorCode::NoError) {
logger.error() << "Failed to get the clientsTable file from the server";
+ endResetModel();
return error;
}
- beginResetModel();
m_clientsTable = QJsonDocument::fromJson(clientsTableString).array();
if (m_clientsTable.isEmpty()) {
@@ -76,6 +76,7 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
error = getWireGuardClients(serverController, container, credentials, count);
}
if (error != ErrorCode::NoError) {
+ endResetModel();
return error;
}
@@ -124,7 +125,6 @@ ErrorCode ClientManagementModel::getOpenVpnClients(ServerController &serverContr
QJsonObject userData;
userData[configKey::clientName] = QString("Client %1").arg(count);
- userData[configKey::container] = container;
client[configKey::userData] = userData;
m_clientsTable.push_back(client);
@@ -165,7 +165,6 @@ ErrorCode ClientManagementModel::getWireGuardClients(ServerController &serverCon
QJsonObject userData;
userData[configKey::clientName] = QString("Client %1").arg(count);
- userData[configKey::container] = container;
client[configKey::userData] = userData;
m_clientsTable.push_back(client);
@@ -211,7 +210,6 @@ ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QSt
QJsonObject userData;
userData[configKey::clientName] = clientName;
- userData[configKey::container] = container;
client[configKey::userData] = userData;
m_clientsTable.push_back(client);
endResetModel();
@@ -371,6 +369,5 @@ QHash ClientManagementModel::roleNames() const
{
QHash roles;
roles[ClientNameRole] = "clientName";
- roles[ContainerNameRole] = "containerName";
return roles;
}
diff --git a/client/ui/models/clientManagementModel.h b/client/ui/models/clientManagementModel.h
index 25089b66..f5312db7 100644
--- a/client/ui/models/clientManagementModel.h
+++ b/client/ui/models/clientManagementModel.h
@@ -11,26 +11,9 @@ class ClientManagementModel : public QAbstractListModel
{
Q_OBJECT
- struct ClientManagementData
- {
- QString userId;
- QJsonObject userData;
-
- bool operator==(const ClientManagementData &r) const
- {
- return userId == r.userId;
- }
-
- bool operator==(const QString &otherUserId) const
- {
- return userId == otherUserId;
- }
- };
-
public:
enum Roles {
ClientNameRole = Qt::UserRole + 1,
- ContainerNameRole,
};
ClientManagementModel(std::shared_ptr settings, QObject *parent = nullptr);
diff --git a/client/ui/qml/Controls2/SwitcherType.qml b/client/ui/qml/Controls2/SwitcherType.qml
index 1dbd0e84..37024872 100644
--- a/client/ui/qml/Controls2/SwitcherType.qml
+++ b/client/ui/qml/Controls2/SwitcherType.qml
@@ -87,6 +87,7 @@ Switch {
id: content
anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
ListItemTitleType {
Layout.fillWidth: true
diff --git a/client/ui/qml/Pages2/PageShare.qml b/client/ui/qml/Pages2/PageShare.qml
index cb847583..e3b28529 100644
--- a/client/ui/qml/Pages2/PageShare.qml
+++ b/client/ui/qml/Pages2/PageShare.qml
@@ -76,6 +76,7 @@ PageType {
}
}
+ property bool isSearchBarVisible: false
property bool showContent: false
property bool shareButtonEnabled: true
property list connectionTypesModel: [
@@ -205,8 +206,8 @@ PageType {
onClicked: {
accessTypeSelector.currentIndex = 1
PageController.showBusyIndicator(true)
- ClientManagementModel.updateModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
- ServersModel.getCurrentlyProcessedServerCredentials())
+ ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
+ ServersModel.getCurrentlyProcessedServerCredentials())
PageController.showBusyIndicator(false)
}
}
@@ -354,12 +355,12 @@ PageType {
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(currentIndex))
- if (accessTypeSelector.currentIndex === 0) {
- fillConnectionTypeModel()
- } else {
+ fillConnectionTypeModel()
+
+ if (accessTypeSelector.currentIndex === 1) {
PageController.showBusyIndicator(true)
- ClientManagementModel.updateModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
- ServersModel.getCurrentlyProcessedServerCredentials())
+ ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
+ ServersModel.getCurrentlyProcessedServerCredentials())
PageController.showBusyIndicator(false)
}
}
@@ -444,9 +445,36 @@ PageType {
Layout.topMargin: 24
Layout.bottomMargin: 16
- visible: accessTypeSelector.currentIndex === 1
+ visible: accessTypeSelector.currentIndex === 1 && !root.isSearchBarVisible
headerText: qsTr("Users")
+ 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
+
+ textFieldPlaceholderText: qsTr("Search")
+ }
+
+ ImageButtonType {
+ image: "qrc:/images/controls/close.svg"
+ imageColor: "#D7D8DB"
+
+ onClicked: function() {
+ root.isSearchBarVisible = false
+ searchTextField.textFieldText = ""
+ }
+ }
}
ListView {
@@ -456,7 +484,15 @@ PageType {
visible: accessTypeSelector.currentIndex === 1
- model: ClientManagementModel
+ model: SortFilterProxyModel {
+ id: proxyClientManagementModel
+ sourceModel: ClientManagementModel
+ filters: RegExpFilter {
+ roleName: "clientName"
+ pattern: ".*" + searchTextField.textFieldText + ".*"
+ caseSensitivity: Qt.CaseInsensitive
+ }
+ }
clip: true
interactive: false
@@ -479,7 +515,6 @@ PageType {
Layout.fillWidth: true
text: clientName
- descriptionText: containerName
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
@@ -510,7 +545,7 @@ PageType {
Layout.bottomMargin: 24
headerText: clientName
- descriptionText: serverSelector.text + ", " + containerName
+ descriptionText: serverSelector.text
}
BasicButtonType {
@@ -620,4 +655,11 @@ PageType {
}
}
}
+ MouseArea {
+ anchors.fill: parent
+ onPressed: function(mouse) {
+ forceActiveFocus()
+ mouse.accepted = false
+ }
+ }
}