added search bar for client management page

This commit is contained in:
vladimir.kuznetsov 2023-11-23 14:32:16 +07:00
parent e8ceeb6e20
commit 5dc3b64e0b
9 changed files with 82 additions and 36 deletions

View file

@ -0,0 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="x, &#195;&#151;, close">
<path id="Vector" d="M18 6L6 18" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_2" d="M6 6L18 18" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 374 B

View file

@ -0,0 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="search">
<path id="Vector" d="M11 19C15.4183 19 19 15.4183 19 11C19 6.58172 15.4183 3 11 3C6.58172 3 3 6.58172 3 11C3 15.4183 6.58172 19 11 19Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path id="Vector_2" d="M21.0004 20.9984L16.6504 16.6484" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 483 B

View file

@ -223,5 +223,7 @@
<file>server_scripts/awg/run_container.sh</file>
<file>server_scripts/awg/Dockerfile</file>
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
<file>images/controls/close.svg</file>
<file>images/controls/search.svg</file>
</qresource>
</RCC>

View file

@ -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);

View file

@ -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);

View file

@ -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<DockerContainer>(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<int, QByteArray> ClientManagementModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[ClientNameRole] = "clientName";
roles[ContainerNameRole] = "containerName";
return roles;
}

View file

@ -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> settings, QObject *parent = nullptr);

View file

@ -87,6 +87,7 @@ Switch {
id: content
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
ListItemTitleType {
Layout.fillWidth: true

View file

@ -76,6 +76,7 @@ PageType {
}
}
property bool isSearchBarVisible: false
property bool showContent: false
property bool shareButtonEnabled: true
property list<QtObject> connectionTypesModel: [
@ -205,7 +206,7 @@ PageType {
onClicked: {
accessTypeSelector.currentIndex = 1
PageController.showBusyIndicator(true)
ClientManagementModel.updateModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials())
PageController.showBusyIndicator(false)
}
@ -354,11 +355,11 @@ PageType {
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(currentIndex))
if (accessTypeSelector.currentIndex === 0) {
fillConnectionTypeModel()
} else {
if (accessTypeSelector.currentIndex === 1) {
PageController.showBusyIndicator(true)
ClientManagementModel.updateModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
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
}
}
}