added search bar for client management page
This commit is contained in:
parent
e8ceeb6e20
commit
5dc3b64e0b
9 changed files with 82 additions and 36 deletions
6
client/images/controls/close.svg
Normal file
6
client/images/controls/close.svg
Normal 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, ×, 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 |
6
client/images/controls/search.svg
Normal file
6
client/images/controls/search.svg
Normal 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 |
|
@ -223,5 +223,7 @@
|
||||||
<file>server_scripts/awg/run_container.sh</file>
|
<file>server_scripts/awg/run_container.sh</file>
|
||||||
<file>server_scripts/awg/Dockerfile</file>
|
<file>server_scripts/awg/Dockerfile</file>
|
||||||
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
|
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
|
||||||
|
<file>images/controls/close.svg</file>
|
||||||
|
<file>images/controls/search.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -232,6 +232,14 @@ void ExportController::exportConfig(const QString &fileName)
|
||||||
SystemController::saveFile(fileName, m_config);
|
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)
|
void ExportController::revokeConfig(const int row, const DockerContainer container, ServerCredentials credentials)
|
||||||
{
|
{
|
||||||
ErrorCode errorCode = m_clientManagementModel->revokeClient(row, container, credentials);
|
ErrorCode errorCode = m_clientManagementModel->revokeClient(row, container, credentials);
|
||||||
|
|
|
@ -39,6 +39,7 @@ public slots:
|
||||||
|
|
||||||
void exportConfig(const QString &fileName);
|
void exportConfig(const QString &fileName);
|
||||||
|
|
||||||
|
void updateClientManagementModel(const DockerContainer container, ServerCredentials credentials);
|
||||||
void revokeConfig(const int row, 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);
|
void renameClient(const int row, const QString &clientName, const DockerContainer container, ServerCredentials credentials);
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,6 @@ QVariant ClientManagementModel::data(const QModelIndex &index, int role) const
|
||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case ClientNameRole: return userData.value(configKey::clientName).toString();
|
case ClientNameRole: return userData.value(configKey::clientName).toString();
|
||||||
case ContainerNameRole:
|
|
||||||
return ContainerProps::containerHumanNames().value(
|
|
||||||
static_cast<DockerContainer>(userData.value(configKey::container).toInt()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
@ -50,6 +47,9 @@ QVariant ClientManagementModel::data(const QModelIndex &index, int role) const
|
||||||
|
|
||||||
ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCredentials credentials)
|
ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCredentials credentials)
|
||||||
{
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_clientsTable = QJsonArray();
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
|
|
||||||
ErrorCode error = ErrorCode::NoError;
|
ErrorCode error = ErrorCode::NoError;
|
||||||
|
@ -60,10 +60,10 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
|
||||||
serverController.getTextFileFromContainer(container, credentials, clientsTableFile, &error);
|
serverController.getTextFileFromContainer(container, credentials, clientsTableFile, &error);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
logger.error() << "Failed to get the clientsTable file from the server";
|
logger.error() << "Failed to get the clientsTable file from the server";
|
||||||
|
endResetModel();
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
beginResetModel();
|
|
||||||
m_clientsTable = QJsonDocument::fromJson(clientsTableString).array();
|
m_clientsTable = QJsonDocument::fromJson(clientsTableString).array();
|
||||||
|
|
||||||
if (m_clientsTable.isEmpty()) {
|
if (m_clientsTable.isEmpty()) {
|
||||||
|
@ -76,6 +76,7 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
|
||||||
error = getWireGuardClients(serverController, container, credentials, count);
|
error = getWireGuardClients(serverController, container, credentials, count);
|
||||||
}
|
}
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
|
endResetModel();
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +125,6 @@ ErrorCode ClientManagementModel::getOpenVpnClients(ServerController &serverContr
|
||||||
|
|
||||||
QJsonObject userData;
|
QJsonObject userData;
|
||||||
userData[configKey::clientName] = QString("Client %1").arg(count);
|
userData[configKey::clientName] = QString("Client %1").arg(count);
|
||||||
userData[configKey::container] = container;
|
|
||||||
client[configKey::userData] = userData;
|
client[configKey::userData] = userData;
|
||||||
|
|
||||||
m_clientsTable.push_back(client);
|
m_clientsTable.push_back(client);
|
||||||
|
@ -165,7 +165,6 @@ ErrorCode ClientManagementModel::getWireGuardClients(ServerController &serverCon
|
||||||
|
|
||||||
QJsonObject userData;
|
QJsonObject userData;
|
||||||
userData[configKey::clientName] = QString("Client %1").arg(count);
|
userData[configKey::clientName] = QString("Client %1").arg(count);
|
||||||
userData[configKey::container] = container;
|
|
||||||
client[configKey::userData] = userData;
|
client[configKey::userData] = userData;
|
||||||
|
|
||||||
m_clientsTable.push_back(client);
|
m_clientsTable.push_back(client);
|
||||||
|
@ -211,7 +210,6 @@ ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QSt
|
||||||
|
|
||||||
QJsonObject userData;
|
QJsonObject userData;
|
||||||
userData[configKey::clientName] = clientName;
|
userData[configKey::clientName] = clientName;
|
||||||
userData[configKey::container] = container;
|
|
||||||
client[configKey::userData] = userData;
|
client[configKey::userData] = userData;
|
||||||
m_clientsTable.push_back(client);
|
m_clientsTable.push_back(client);
|
||||||
endResetModel();
|
endResetModel();
|
||||||
|
@ -371,6 +369,5 @@ QHash<int, QByteArray> ClientManagementModel::roleNames() const
|
||||||
{
|
{
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
roles[ClientNameRole] = "clientName";
|
roles[ClientNameRole] = "clientName";
|
||||||
roles[ContainerNameRole] = "containerName";
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,26 +11,9 @@ class ClientManagementModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
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:
|
public:
|
||||||
enum Roles {
|
enum Roles {
|
||||||
ClientNameRole = Qt::UserRole + 1,
|
ClientNameRole = Qt::UserRole + 1,
|
||||||
ContainerNameRole,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ClientManagementModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
ClientManagementModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
|
@ -87,6 +87,7 @@ Switch {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
|
||||||
ListItemTitleType {
|
ListItemTitleType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
@ -76,6 +76,7 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property bool isSearchBarVisible: false
|
||||||
property bool showContent: false
|
property bool showContent: false
|
||||||
property bool shareButtonEnabled: true
|
property bool shareButtonEnabled: true
|
||||||
property list<QtObject> connectionTypesModel: [
|
property list<QtObject> connectionTypesModel: [
|
||||||
|
@ -205,8 +206,8 @@ PageType {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
accessTypeSelector.currentIndex = 1
|
accessTypeSelector.currentIndex = 1
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
ClientManagementModel.updateModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
|
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
|
||||||
ServersModel.getCurrentlyProcessedServerCredentials())
|
ServersModel.getCurrentlyProcessedServerCredentials())
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,12 +355,12 @@ PageType {
|
||||||
|
|
||||||
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(currentIndex))
|
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(currentIndex))
|
||||||
|
|
||||||
if (accessTypeSelector.currentIndex === 0) {
|
fillConnectionTypeModel()
|
||||||
fillConnectionTypeModel()
|
|
||||||
} else {
|
if (accessTypeSelector.currentIndex === 1) {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
ClientManagementModel.updateModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
|
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
|
||||||
ServersModel.getCurrentlyProcessedServerCredentials())
|
ServersModel.getCurrentlyProcessedServerCredentials())
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -444,9 +445,36 @@ PageType {
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 16
|
Layout.bottomMargin: 16
|
||||||
|
|
||||||
visible: accessTypeSelector.currentIndex === 1
|
visible: accessTypeSelector.currentIndex === 1 && !root.isSearchBarVisible
|
||||||
|
|
||||||
headerText: qsTr("Users")
|
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 {
|
ListView {
|
||||||
|
@ -456,7 +484,15 @@ PageType {
|
||||||
|
|
||||||
visible: accessTypeSelector.currentIndex === 1
|
visible: accessTypeSelector.currentIndex === 1
|
||||||
|
|
||||||
model: ClientManagementModel
|
model: SortFilterProxyModel {
|
||||||
|
id: proxyClientManagementModel
|
||||||
|
sourceModel: ClientManagementModel
|
||||||
|
filters: RegExpFilter {
|
||||||
|
roleName: "clientName"
|
||||||
|
pattern: ".*" + searchTextField.textFieldText + ".*"
|
||||||
|
caseSensitivity: Qt.CaseInsensitive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: false
|
||||||
|
@ -479,7 +515,6 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: clientName
|
text: clientName
|
||||||
descriptionText: containerName
|
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
|
@ -510,7 +545,7 @@ PageType {
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
headerText: clientName
|
headerText: clientName
|
||||||
descriptionText: serverSelector.text + ", " + containerName
|
descriptionText: serverSelector.text
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
@ -620,4 +655,11 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onPressed: function(mouse) {
|
||||||
|
forceActiveFocus()
|
||||||
|
mouse.accepted = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue