From 4222ad1a2b044ca80c5a7e1e5f6c6767e29a330f Mon Sep 17 00:00:00 2001
From: VGolovchenko <v.golovchenko3@gmail.com>
Date: Sat, 11 Jul 2020 20:02:59 +0300
Subject: [PATCH] add CertificateManager page and logic

add svg icon
---
 CellFrameDashboard.pro                        |   2 +
 .../CellFrameDashboardGUI.pro                 |   6 +-
 .../DapServiceController.cpp                  |  10 +
 CellFrameDashboardGUI/DapServiceController.h  |   8 +-
 CellFrameDashboardGUI/main.cpp                |  20 ++
 CellFrameDashboardGUI/qml.qrc                 |  34 ++
 .../icons/Certificates/btn_actions.svg        |  16 +
 .../icons/Certificates/btn_actions_hover.svg  |  16 +
 .../Certificates/btn_actions_no-active.svg    |   6 +
 .../icons/Certificates/btn_create_done.svg    |  16 +
 .../Certificates/btn_create_done_hover.svg    |  16 +
 .../btn_create_done_no-active.svg             |   6 +
 .../Certificates/cellframe-logo-dashboard.svg |  13 +
 .../icons/Certificates/close_icon.svg         |   4 +
 .../icons/Certificates/close_icon_hover.svg   |   4 +
 .../icons/Certificates/ic_arrow_up.svg        |   6 +
 .../resources/icons/Certificates/ic_info.svg  |   6 +
 .../icons/Certificates/ic_search.svg          |   5 +
 .../icons/Certificates/icon_arrow_down.svg    |   6 +
 .../icons/Certificates/icon_certificates.svg  |  23 ++
 .../Certificates/icon_certificates_hover.svg  |  23 ++
 .../icons/Certificates/radio_off_dark.svg     |   4 +
 .../icons/Certificates/radio_on_dark.svg      |   4 +
 .../screen/DapMainApplicationWindow.qml       |  32 +-
 .../Certificates/CertificateInfoItem.qml      |  79 +++++
 .../CertificatesActionsButtonList.qml         | 232 +++++++++++++
 .../Certificates/CertificatesListView.qml     | 169 +++++++++
 .../Certificates/CertificatesLogic.qml        | 288 ++++++++++++++++
 .../CertificatesMainPage.qml.autosave         |  23 ++
 .../Certificates/CertificatesModels.qml       | 198 +++++++++++
 .../Certificates/CreateCertificateItem.qml    | 232 +++++++++++++
 .../Certificates/CreateFinishedItem.qml       |  92 +++++
 .../Certificates/DapCertificatesMainPage.qml  | 320 ++++++++++++++++++
 .../desktop/Certificates/HeaderItem.qml       |  58 ++++
 .../Certificates/models/FindDelegateModel.qml |  73 ++++
 .../Certificates/parts/CloseButton.qml        |  22 ++
 .../parts/CreateCertificateModel.qml          |  15 +
 .../Certificates/parts/FindDelegateModel.qml  |  73 ++++
 .../desktop/Certificates/parts/InputField.qml |  78 +++++
 .../parts/PlaceholderTextView.qml.autosave    |  13 +
 .../Certificates/parts/SearchInputBox.qml     | 103 ++++++
 .../Certificates/parts/TextInputFilter.qml    |  70 ++++
 .../Certificates/parts/TitleTextView.qml      |  39 +++
 .../desktop/Certificates/parts/ToolButton.qml |  39 +++
 .../desktop/Certificates/parts/Utils.qml      |  72 ++++
 .../DapInputNewWalletNameRightPanel.qml       |   4 +-
 .../CellFrameDashboardService.pro             |   8 +
 .../DapServiceController.cpp                  |   3 +
 .../DapServiceController.h                    |   2 +
 49 files changed, 2587 insertions(+), 4 deletions(-)
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/btn_actions.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_hover.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_no-active.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_hover.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_no-active.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/cellframe-logo-dashboard.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/close_icon.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/close_icon_hover.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/ic_arrow_up.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/ic_info.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/ic_search.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/icon_arrow_down.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates_hover.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/radio_off_dark.svg
 create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/radio_on_dark.svg
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CertificateInfoItem.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesActionsButtonList.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesListView.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesLogic.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesMainPage.qml.autosave
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesModels.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CreateCertificateItem.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CreateFinishedItem.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/DapCertificatesMainPage.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/HeaderItem.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/models/FindDelegateModel.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/CloseButton.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/CreateCertificateModel.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/FindDelegateModel.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/InputField.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/PlaceholderTextView.qml.autosave
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/SearchInputBox.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/TextInputFilter.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/TitleTextView.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/ToolButton.qml
 create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/Utils.qml

diff --git a/CellFrameDashboard.pro b/CellFrameDashboard.pro
index 14df6c1..d235244 100755
--- a/CellFrameDashboard.pro
+++ b/CellFrameDashboard.pro
@@ -1,6 +1,8 @@
 TEMPLATE = subdirs
 SUBDIRS = CellFrameDashboardGUI CellFrameDashboardService
 
+
+
 CellFrameDashboardGUI.subdir = CellFrameDashboardGUI
 CellFrameDashboardService.subdir = CellFrameDashboardService
 CellFrameDashboardGUI.depends = CellFrameDashboardService
diff --git a/CellFrameDashboardGUI/CellFrameDashboardGUI.pro b/CellFrameDashboardGUI/CellFrameDashboardGUI.pro
index ba3fa42..ff564e4 100755
--- a/CellFrameDashboardGUI/CellFrameDashboardGUI.pro
+++ b/CellFrameDashboardGUI/CellFrameDashboardGUI.pro
@@ -1,8 +1,9 @@
-QT += qml quick widgets
+QT += qml quick widgets svg
 
 TEMPLATE = app
 CONFIG += c++11
 
+LIBS += -ldl
 
 !defined(BRAND,var){
 #  Default brand
@@ -18,11 +19,14 @@ VER_PAT = 3
 win32 {
     VERSION = $${VER_MAJ}.$${VER_MIN}.$$VER_PAT
     DEFINES += CLI_PATH=\\\"cellframe-node-cli.exe\\\"
+    DEFINES += TOOLS_PATH=\\\"cellframe-node-tool.exe\\\"
     DEFINES += HAVE_STRNDUP
 }
 else {
     VERSION = $$VER_MAJ\.$$VER_MIN\-$$VER_PAT
     DEFINES += CLI_PATH=\\\"/opt/cellframe-node/bin/cellframe-node-cli\\\"
+    DEFINES += TOOLS_PATH=\\\"/opt/cellframe-node/bin/cellframe-node-tool\\\"
+    DEFINES += CONFIG_PATH=\\\"/opt/cellframe-node/bin/cellframe-node-cli\\\"
 }
 
 # The following define makes your compiler emit warnings if you use
diff --git a/CellFrameDashboardGUI/DapServiceController.cpp b/CellFrameDashboardGUI/DapServiceController.cpp
index d85a1c6..e34ecde 100644
--- a/CellFrameDashboardGUI/DapServiceController.cpp
+++ b/CellFrameDashboardGUI/DapServiceController.cpp
@@ -79,7 +79,10 @@ void DapServiceController::requestToService(const QString &asServiceName, const
                                             const QVariant &arg5, const QVariant &arg6, const QVariant &arg7,
                                             const QVariant &arg8, const QVariant &arg9, const QVariant &arg10)
 {
+
     DapAbstractCommand * transceiver = dynamic_cast<DapAbstractCommand*>(m_DAPRpcSocket->findService(asServiceName));
+//    qDebug() << "DapServiceController::requestToService, asServiceName:" << asServiceName << arg1 << arg2 << arg3 << arg4 << arg5
+//             << "transceiver:" << transceiver;
     Q_ASSERT(transceiver);
     disconnect(transceiver, SIGNAL(serviceResponded(QVariant)), this, SLOT(findEmittedSignal(QVariant)));
     connect(transceiver, SIGNAL(serviceResponded(QVariant)), SLOT(findEmittedSignal(QVariant)));
@@ -95,6 +98,7 @@ void DapServiceController::notifyService(const QString &asServiceName, const QVa
                                          const QVariant &arg5, const QVariant &arg6, const QVariant &arg7,
                                          const QVariant &arg8, const QVariant &arg9, const QVariant &arg10)
 {
+    qDebug() << "DapServiceController::notifyService" << asServiceName << arg1 << arg2 << arg3 << arg4 << arg5;
     DapAbstractCommand * transceiver = dynamic_cast<DapAbstractCommand*>(m_DAPRpcSocket->findService(asServiceName));
 
     Q_ASSERT(transceiver);
@@ -105,6 +109,11 @@ void DapServiceController::notifyService(const QString &asServiceName, const QVa
 /// Register command.
 void DapServiceController::registerCommand()
 {
+
+    m_transceivers.append(qMakePair(dynamic_cast<DapAbstractCommand*>(m_DAPRpcSocket->addService(
+                                    new DapCertificateManagerCommands(DapCertificateCommands::serviceName(), m_DAPRpcSocket)))
+                                    , QString("certificateManagerOperationResult")));
+
     // Application shutdown team
     m_transceivers.append(qMakePair(dynamic_cast<DapAbstractCommand*>(m_DAPRpcSocket->addService(new DapQuitApplicationCommand("DapQuitApplicationCommand", m_DAPRpcSocket))), QString()));
     // GUI client activation command in case it is minimized/expanded
@@ -187,6 +196,7 @@ void DapServiceController::registerCommand()
 void DapServiceController::findEmittedSignal(const QVariant &aValue)
 {
     DapAbstractCommand * transceiver = dynamic_cast<DapAbstractCommand *>(sender());
+    //qDebug() << "findEmittedSignal, transceiver:" << transceiver  << ", value:" << aValue;
     Q_ASSERT(transceiver);
     auto service = std::find_if(m_transceivers.begin(), m_transceivers.end(), [=] (const QPair<DapAbstractCommand*, QString>& it) 
     {
diff --git a/CellFrameDashboardGUI/DapServiceController.h b/CellFrameDashboardGUI/DapServiceController.h
index 93efd97..babc97c 100644
--- a/CellFrameDashboardGUI/DapServiceController.h
+++ b/CellFrameDashboardGUI/DapServiceController.h
@@ -14,6 +14,7 @@
 #include "handlers/DapAbstractCommand.h"
 #include "handlers/DapQuitApplicationCommand.h"
 #include "handlers/DapActivateClientCommand.h"
+#include "handlers/DapCertificateManagerCommands.h"
 #include "handlers/DapUpdateLogsCommand.h"
 #include "handlers/DapAddWalletCommand.h"
 #include "handlers/DapGetWalletsInfoCommand.h"
@@ -29,6 +30,8 @@
 #include "handlers/DapGetHistoryExecutedCmdCommand.h"
 #include "handlers/DapSaveHistoryExecutedCmdCommand.h"
 
+
+
 class DapServiceController : public QObject
 {
     Q_OBJECT
@@ -81,7 +84,7 @@ public:
     /// Application version.
     Q_PROPERTY(QString Version MEMBER m_sVersion READ getVersion NOTIFY versionChanged)
 
-    Q_PROPERTY(QString CurrentNetwork MEMBER m_sVersion READ getCurrentNetwork WRITE setCurrentNetwork NOTIFY currentNetworkChanged)
+    Q_PROPERTY(QString CurrentNetwork MEMBER m_sCurrentNetwork READ getCurrentNetwork WRITE setCurrentNetwork NOTIFY currentNetworkChanged)
 
     Q_PROPERTY(int IndexCurrentNetwork MEMBER m_iIndexCurrentNetwork READ getIndexCurrentNetwork WRITE setIndexCurrentNetwork NOTIFY indexCurrentNetworkChanged)
 
@@ -154,6 +157,9 @@ signals:
     /// The signal is emitted when receiving a history of commands executed by the cli handler.
     /// @param aHistory History of commands executed by cli handler.
     void historyExecutedCmdReceived(const QVariant& aHistory);
+
+     //соблюдаем оригинальную типизацию в сигналах, хотя тут лучше MapVariantList или что-то подобное
+    void certificateManagerOperationResult(const QVariant& result);
     
 private slots:
     /// Register command.
diff --git a/CellFrameDashboardGUI/main.cpp b/CellFrameDashboardGUI/main.cpp
index a004129..8aec284 100644
--- a/CellFrameDashboardGUI/main.cpp
+++ b/CellFrameDashboardGUI/main.cpp
@@ -53,11 +53,31 @@ int main(int argc, char *argv[])
     DapServiceController &controller = DapServiceController::getInstance();
     controller.init(&dapServiceClient);
     dapServiceClient.init();
+
+
+    //register only enums
+    qmlRegisterUncreatableType<DapCertificateType>("DapCertificateManager.Commands", 1, 0, "DapCertificateType"
+                         , "Error create DapCertificateType");
+
+    //register enums and constant property as singletone
+    qmlRegisterSingletonType<DapCertificateCommands>("DapCertificateManager.Commands", 1, 0, "DapCertificateCommands"
+            , [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * {
+                    Q_UNUSED(engine)
+                    Q_UNUSED(scriptEngine)
+
+                    //qInfo() << "DapCertificateCommands initialize in Qml";
+                    QQmlEngine::setObjectOwnership(DapCertificateCommands::instance()
+                                                   , QQmlEngine::ObjectOwnership::CppOwnership);
+                    return DapCertificateCommands::instance();
+            });
+
+
     qmlRegisterType<DapLogMessage>("Demlabs", 1, 0, "DapLogMessage");
     qmlRegisterType<DapWallet>("Demlabs", 1, 0, "DapWallet");
     qmlRegisterType<DapWalletToken>("Demlabs", 1, 0, "DapWalletToken");
     qRegisterMetaType<DapWallet>();
     qRegisterMetaType<DapWalletToken>();
+
     QQmlApplicationEngine engine;
     engine.rootContext()->setContextProperty("dapServiceController", &DapServiceController::getInstance());
     engine.rootContext()->setContextProperty("pt", 1);
diff --git a/CellFrameDashboardGUI/qml.qrc b/CellFrameDashboardGUI/qml.qrc
index 2458100..398196c 100755
--- a/CellFrameDashboardGUI/qml.qrc
+++ b/CellFrameDashboardGUI/qml.qrc
@@ -149,5 +149,39 @@
         <file>resources/icons/next_year_icon.png</file>
         <file>resources/icons/previous_month_icon.png</file>
         <file>resources/icons/previous_year_icon.png</file>
+        <file>screen/desktop/Certificates/DapCertificatesMainPage.qml</file>
+        <file>screen/desktop/Certificates/HeaderItem.qml</file>
+        <file>resources/icons/Certificates/btn_actions.svg</file>
+        <file>resources/icons/Certificates/btn_actions_hover.svg</file>
+        <file>resources/icons/Certificates/btn_actions_no-active.svg</file>
+        <file>resources/icons/Certificates/btn_create_done.svg</file>
+        <file>resources/icons/Certificates/btn_create_done_hover.svg</file>
+        <file>resources/icons/Certificates/btn_create_done_no-active.svg</file>
+        <file>resources/icons/Certificates/cellframe-logo-dashboard.svg</file>
+        <file>resources/icons/Certificates/close_icon.svg</file>
+        <file>resources/icons/Certificates/close_icon_hover.svg</file>
+        <file>resources/icons/Certificates/ic_arrow_up.svg</file>
+        <file>resources/icons/Certificates/ic_info.svg</file>
+        <file>resources/icons/Certificates/icon_arrow_down.svg</file>
+        <file>resources/icons/Certificates/icon_certificates.svg</file>
+        <file>resources/icons/Certificates/icon_certificates_hover.svg</file>
+        <file>resources/icons/Certificates/ic_search.svg</file>
+        <file>resources/icons/Certificates/radio_off_dark.svg</file>
+        <file>resources/icons/Certificates/radio_on_dark.svg</file>
+        <file>screen/desktop/Certificates/parts/SearchInputBox.qml</file>
+        <file>screen/desktop/Certificates/CertificatesModels.qml</file>
+        <file>screen/desktop/Certificates/CertificatesListView.qml</file>
+        <file>screen/desktop/Certificates/CertificatesActionsButtonList.qml</file>
+        <file>screen/desktop/Certificates/parts/TextInputFilter.qml</file>
+        <file>screen/desktop/Certificates/CreateCertificateItem.qml</file>
+        <file>screen/desktop/Certificates/CertificateInfoItem.qml</file>
+        <file>screen/desktop/Certificates/CreateFinishedItem.qml</file>
+        <file>screen/desktop/Certificates/parts/ToolButton.qml</file>
+        <file>screen/desktop/Certificates/parts/CloseButton.qml</file>
+        <file>screen/desktop/Certificates/parts/InputField.qml</file>
+        <file>screen/desktop/Certificates/models/FindDelegateModel.qml</file>
+        <file>screen/desktop/Certificates/CertificatesLogic.qml</file>
+        <file>screen/desktop/Certificates/parts/TitleTextView.qml</file>
+        <file>screen/desktop/Certificates/parts/Utils.qml</file>
     </qresource>
 </RCC>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions.svg b/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions.svg
new file mode 100644
index 0000000..7b6142b
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions.svg
@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="353" height="39" viewBox="0 0 353 39">
+  <defs>
+    <filter id="bg" x="0" y="0" width="353" height="39" filterUnits="userSpaceOnUse">
+      <feOffset dy="1" input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="0.5" result="blur"/>
+      <feFlood flood-color="#010143" flood-opacity="0.2"/>
+      <feComposite operator="in" in2="blur"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+  </defs>
+  <g id="btn_actions" transform="translate(1.5 0.5)">
+    <g transform="matrix(1, 0, 0, 1, -1.5, -0.5)" filter="url(#bg)">
+      <rect id="bg-2" data-name="bg" width="350" height="36" rx="4" transform="translate(1.5 0.5)" fill="#271c4e"/>
+    </g>
+  </g>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_hover.svg b/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_hover.svg
new file mode 100644
index 0000000..be1332a
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_hover.svg
@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="353" height="39" viewBox="0 0 353 39">
+  <defs>
+    <filter id="bg" x="0" y="0" width="353" height="39" filterUnits="userSpaceOnUse">
+      <feOffset dy="1" input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="0.5" result="blur"/>
+      <feFlood flood-color="#43011a" flood-opacity="0.2"/>
+      <feComposite operator="in" in2="blur"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+  </defs>
+  <g id="btn_actions_hover" transform="translate(1.5 0.5)">
+    <g transform="matrix(1, 0, 0, 1, -1.5, -0.5)" filter="url(#bg)">
+      <rect id="bg-2" data-name="bg" width="350" height="36" rx="4" transform="translate(1.5 0.5)" fill="#d51f5d"/>
+    </g>
+  </g>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_no-active.svg b/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_no-active.svg
new file mode 100644
index 0000000..9752e06
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_no-active.svg
@@ -0,0 +1,6 @@
+<svg id="btn_actions_no-active" xmlns="http://www.w3.org/2000/svg" width="350" height="36" viewBox="0 0 350 36">
+  <g id="bg" fill="none" stroke="#211a3a" stroke-width="1">
+    <rect width="350" height="36" rx="4" stroke="none"/>
+    <rect x="0.5" y="0.5" width="349" height="35" rx="3.5" fill="none"/>
+  </g>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done.svg b/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done.svg
new file mode 100644
index 0000000..87d426b
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done.svg
@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="135" height="39" viewBox="0 0 135 39">
+  <defs>
+    <filter id="bg_send_btn" x="0" y="0" width="135" height="39" filterUnits="userSpaceOnUse">
+      <feOffset dy="1" input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="0.5" result="blur"/>
+      <feFlood flood-color="#010143" flood-opacity="0.2"/>
+      <feComposite operator="in" in2="blur"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+  </defs>
+  <g id="btn_create_done" transform="translate(1.5 0.5)">
+    <g transform="matrix(1, 0, 0, 1, -1.5, -0.5)" filter="url(#bg_send_btn)">
+      <rect id="bg_send_btn-2" data-name="bg_send_btn" width="132" height="36" rx="4" transform="translate(1.5 0.5)" fill="#271c4e"/>
+    </g>
+  </g>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_hover.svg b/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_hover.svg
new file mode 100644
index 0000000..fa66cc6
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_hover.svg
@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="135" height="39" viewBox="0 0 135 39">
+  <defs>
+    <filter id="bg_send_btn" x="0" y="0" width="135" height="39" filterUnits="userSpaceOnUse">
+      <feOffset dy="1" input="SourceAlpha"/>
+      <feGaussianBlur stdDeviation="0.5" result="blur"/>
+      <feFlood flood-color="#43011a" flood-opacity="0.2"/>
+      <feComposite operator="in" in2="blur"/>
+      <feComposite in="SourceGraphic"/>
+    </filter>
+  </defs>
+  <g id="btn_create_done_hover" transform="translate(1.5 0.5)">
+    <g transform="matrix(1, 0, 0, 1, -1.5, -0.5)" filter="url(#bg_send_btn)">
+      <rect id="bg_send_btn-2" data-name="bg_send_btn" width="132" height="36" rx="4" transform="translate(1.5 0.5)" fill="#d51f5d"/>
+    </g>
+  </g>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_no-active.svg b/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_no-active.svg
new file mode 100644
index 0000000..5af57f3
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_no-active.svg
@@ -0,0 +1,6 @@
+<svg id="btn_create_done_no-active" xmlns="http://www.w3.org/2000/svg" width="132" height="36" viewBox="0 0 132 36">
+  <g id="bg_send_btn" fill="none" stroke="#3e3853" stroke-width="1">
+    <rect width="132" height="36" rx="4" stroke="none"/>
+    <rect x="0.5" y="0.5" width="131" height="35" rx="3.5" fill="none"/>
+  </g>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/cellframe-logo-dashboard.svg b/CellFrameDashboardGUI/resources/icons/Certificates/cellframe-logo-dashboard.svg
new file mode 100644
index 0000000..20df02e
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/cellframe-logo-dashboard.svg
@@ -0,0 +1,13 @@
+<svg id="cellframe-logo-dashboard" xmlns="http://www.w3.org/2000/svg" width="111" height="24" viewBox="0 0 111 24">
+  <g id="Слой6">
+    <path id="Path_1417" data-name="Path 1417" d="M1154.829,228.311c-.117.2-.024.515.646.4a18.624,18.624,0,0,1,4.8-.217,13.765,13.765,0,0,1,3.538.851c.552.18,1.149.458,1.4.362s.229-.475-.031-.858a4.857,4.857,0,0,0-1.613-1.381,7.563,7.563,0,0,0-3.711-.914,8.975,8.975,0,0,0-3.715.825A3.206,3.206,0,0,0,1154.829,228.311Z" transform="translate(-1148.635 -226.547)" fill="#fff" fill-rule="evenodd"/>
+    <g id="Group_2119" data-name="Group 2119" transform="translate(17.602 24) rotate(-178.904)">
+      <path id="Path_1418" data-name="Path 1418" d="M.043,1.76c-.117.2-.023.515.646.4a18.618,18.618,0,0,1,4.8-.213A13.781,13.781,0,0,1,9.023,2.8c.552.181,1.149.459,1.4.363s.228-.475-.031-.858A4.87,4.87,0,0,0,8.778.919,7.572,7.572,0,0,0,5.066,0,8.968,8.968,0,0,0,1.351.823,3.2,3.2,0,0,0,.043,1.76Z" transform="translate(0 0)" fill="#fff" fill-rule="evenodd"/>
+    </g>
+    <path id="Path_1419" data-name="Path 1419" d="M179.177,549.52a10.834,10.834,0,0,1,3.707.794c2.762,1.127,4.571,3.065,5.121,2.914.422-.116.328-1.378.064-2.315-.418-1.481-.882-1.753-.7-1.947.235-.248,1.622.684,3.015,2.579a11.7,11.7,0,0,1,2.2,6.275,9.048,9.048,0,0,1-2.876,7.24,11,11,0,0,1-4.544,2.522,9.221,9.221,0,0,1-4.278.267,12.906,12.906,0,0,1-5.741-2.327c-.968-.65-1.693-1.451-2.054-1.142-.392.336-.215,1.519.171,2.609.3.844.783,1.458.46,1.56-.479.151-2.49-1.755-3.681-3.831A10.562,10.562,0,0,1,168.6,559a10.167,10.167,0,0,1,.257-2.1,8.871,8.871,0,0,1,1.612-3.45,10.422,10.422,0,0,1,3.355-2.74A10.186,10.186,0,0,1,179.177,549.52Zm.563.5a9.915,9.915,0,0,0-4.558.687,9.122,9.122,0,0,0-3.3,2.1,8.707,8.707,0,0,0-2.128,3.16,9.876,9.876,0,0,0-.239,5.7,7.726,7.726,0,0,0,1.634,3.32c.93,1.079.46-3.509,1.768-2.554.771.562,1.9,2.31,4.332,3.639a9.783,9.783,0,0,0,6.8,1.294,11.456,11.456,0,0,0,5.011-2.448,7.981,7.981,0,0,0,2.555-3.705,9.119,9.119,0,0,0,.408-3.566c-.312-2.934-1.931-5.7-2.337-5.333-.36.321-.189,3.433-1.186,2.917a20.36,20.36,0,0,1-2.389-2.157,16.951,16.951,0,0,0-2.362-1.729A8.667,8.667,0,0,0,179.74,550.018Z" transform="translate(-168.598 -546.827)" fill="#fff" fill-rule="evenodd"/>
+    <g id="Group_2120" data-name="Group 2120" transform="translate(1.079 3.813)">
+      <path id="Path_1420" data-name="Path 1420" d="M387.68,550.9a9.564,9.564,0,0,1,3.474.748,8.714,8.714,0,0,1,3.85,3.066c1.278,1.789,1.705,3.825,2.466,3.554a3.675,3.675,0,0,0,1.48-1.483c.484-.825.967-.4,1.167.758a7.3,7.3,0,0,1-.3,3.472,8.165,8.165,0,0,1-2.192,3.576,8.705,8.705,0,0,1-3.49,2.057,9.94,9.94,0,0,1-4.653.3,9.409,9.409,0,0,1-5.48-3.12,10.327,10.327,0,0,1-1.4-1.964,11.7,11.7,0,0,0-1.049-1.685c-.429-.435-.755-.5-1.354.231-.324.4-.723,1.592-1.3.943a3.624,3.624,0,0,1-.477-1.928,8.5,8.5,0,0,1,1.441-4.61,9.439,9.439,0,0,1,3.086-2.789A8.91,8.91,0,0,1,387.68,550.9Zm.174.516a7.77,7.77,0,0,0-4.177.844,8,8,0,0,0-3.483,3.349,5.062,5.062,0,0,0-.674,2.844c.133.515,1.745-1.75,2.486-.917.59.664.408,1.609,1.109,3.247a8.727,8.727,0,0,0,8.075,5.581,7.759,7.759,0,0,0,3.476-.606,7.9,7.9,0,0,0,2.632-1.767,6.493,6.493,0,0,0,1.64-2.593c.378-1,.528-2.06-.05-1.928-.724.166-1.346,1.161-1.947,1.2-.648.039-.718-.935-1.135-2.315a11.821,11.821,0,0,0-1.088-2.6,8.024,8.024,0,0,0-6.864-4.34Z" transform="translate(-378.418 -550.902)" fill="#fff" fill-rule="evenodd"/>
+    </g>
+  </g>
+  <path id="Path_1429" data-name="Path 1429" d="M19.7-173.34a4.735,4.735,0,0,1-1.885-.365,4.01,4.01,0,0,1-1.46-1.064,4.88,4.88,0,0,1-.942-1.724,7.594,7.594,0,0,1-.333-2.347,6.8,6.8,0,0,1,.376-2.347,5.151,5.151,0,0,1,1.013-1.724,4.278,4.278,0,0,1,1.488-1.064,4.554,4.554,0,0,1,1.814-.365,6.022,6.022,0,0,1,1.1.091,6.341,6.341,0,0,1,.85.213,3.907,3.907,0,0,1,.588.243,3.275,3.275,0,0,1,.312.182l-.4,1.215a2.143,2.143,0,0,0-.368-.2q-.241-.106-.546-.213a4.638,4.638,0,0,0-.666-.175,3.918,3.918,0,0,0-.73-.068,3.3,3.3,0,0,0-1.4.289,2.923,2.923,0,0,0-1.063.836,3.862,3.862,0,0,0-.673,1.329,6.121,6.121,0,0,0-.234,1.755,6.693,6.693,0,0,0,.206,1.717,3.876,3.876,0,0,0,.617,1.329,2.806,2.806,0,0,0,1.028.858,3.217,3.217,0,0,0,1.439.3,4.941,4.941,0,0,0,1.573-.213,6.641,6.641,0,0,0,.935-.38l.354,1.215a1.942,1.942,0,0,1-.354.19,4.635,4.635,0,0,1-.638.22,7.492,7.492,0,0,1-.893.182A7.522,7.522,0,0,1,19.7-173.34Zm4.564-.228V-184.1h6v1.261h-4.62v3.13h4.11v1.231h-4.11v3.646h4.975v1.261Zm14-1.276v1.276h-5.91V-184.1h1.375v9.253Zm7.356,0v1.276h-5.91V-184.1h1.375v9.253Zm1.446,1.276V-184.1h5.924v1.261H48.442v3.175h4.039v1.246H48.442v4.847Zm12.415-4.406q.227.3.574.8t.716,1.094q.368.6.73,1.253a13.053,13.053,0,0,1,.617,1.261h-1.5q-.283-.577-.617-1.17t-.673-1.132q-.34-.539-.673-1.01t-.6-.82q-.184.015-.376.015H56.053v4.117H54.678v-10.377a7.272,7.272,0,0,1,1.3-.205q.716-.053,1.311-.053a5.091,5.091,0,0,1,3.153.836,2.95,2.95,0,0,1,1.084,2.492,3.063,3.063,0,0,1-.517,1.793A3.053,3.053,0,0,1,59.483-177.974ZM57.4-182.912q-.879,0-1.346.046v3.965h.978a9.672,9.672,0,0,0,1.276-.076,2.753,2.753,0,0,0,.957-.289,1.484,1.484,0,0,0,.6-.6,2.13,2.13,0,0,0,.213-1.026,2.066,2.066,0,0,0-.213-.988,1.639,1.639,0,0,0-.574-.623,2.4,2.4,0,0,0-.85-.319A5.681,5.681,0,0,0,57.4-182.912Zm13.152,9.344q-.241-.684-.454-1.345t-.439-1.345h-4.45l-.893,2.689H62.884q.567-1.671,1.063-3.092t.971-2.7q.475-1.276.942-2.438t.978-2.3H68.1q.51,1.14.978,2.3t.942,2.438q.475,1.276.971,2.7t1.063,3.092Zm-1.29-3.9q-.454-1.322-.9-2.56t-.928-2.378q-.5,1.139-.942,2.378t-.886,2.56Zm8.532,2.446q-.142-.365-.376-.927t-.5-1.215q-.269-.653-.574-1.345t-.574-1.307q-.269-.615-.5-1.1t-.376-.744q-.156,1.793-.255,3.882t-.17,4.216H73.117q.057-1.367.128-2.758t.163-2.735q.092-1.345.2-2.621t.234-2.416h1.2q.383.669.822,1.58t.879,1.907q.439,1,.85,1.99t.751,1.816q.34-.82.751-1.816t.85-1.99q.439-1,.879-1.907t.822-1.58h1.2q.482,5.09.723,10.529H82.23q-.071-2.127-.17-4.216t-.255-3.882q-.142.258-.376.744t-.5,1.1q-.269.615-.574,1.307t-.574,1.345q-.269.653-.5,1.215t-.376.927Zm7.937,1.459V-184.1h6v1.261h-4.62v3.13h4.11v1.231h-4.11v3.646H92.08v1.261Z" transform="translate(18.92 190.34)" fill="#fff"/>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/close_icon.svg b/CellFrameDashboardGUI/resources/icons/Certificates/close_icon.svg
new file mode 100644
index 0000000..3328bb5
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/close_icon.svg
@@ -0,0 +1,4 @@
+<svg id="close_icon" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+  <rect id="bg_close_icon" width="20" height="20" fill="none"/>
+  <path id="close_object_icon" d="M23.442,23l4.467-4.467a.312.312,0,0,0-.442-.442L23,22.558l-4.467-4.467a.312.312,0,1,0-.442.442L22.558,23l-4.467,4.467a.312.312,0,1,0,.442.442L23,23.442l4.467,4.467a.312.312,0,0,0,.442-.442Z" transform="translate(-12.5 -12.5)" fill="#070023"/>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/close_icon_hover.svg b/CellFrameDashboardGUI/resources/icons/Certificates/close_icon_hover.svg
new file mode 100644
index 0000000..615605b
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/close_icon_hover.svg
@@ -0,0 +1,4 @@
+<svg id="close_icon_hover" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+  <rect id="bg_close_icon" width="20" height="20" fill="none"/>
+  <path id="close_object_icon" d="M23.442,23l4.467-4.467a.312.312,0,0,0-.442-.442L23,22.558l-4.467-4.467a.312.312,0,1,0-.442.442L22.558,23l-4.467,4.467a.312.312,0,1,0,.442.442L23,23.442l4.467,4.467a.312.312,0,0,0,.442-.442Z" transform="translate(-12.5 -12.5)" fill="#d51f5d"/>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/ic_arrow_up.svg b/CellFrameDashboardGUI/resources/icons/Certificates/ic_arrow_up.svg
new file mode 100644
index 0000000..d3f9b62
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/ic_arrow_up.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+  <g id="ic_arrow_up" transform="translate(24.105 24) rotate(180)">
+    <path id="path" d="M0,0,5,5l5-5Z" transform="translate(7.285 10)" fill="#070023"/>
+    <rect id="rectangle" width="24" height="24" transform="translate(0.105)" fill="none"/>
+  </g>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/ic_info.svg b/CellFrameDashboardGUI/resources/icons/Certificates/ic_info.svg
new file mode 100644
index 0000000..fa1e407
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/ic_info.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30">
+  <g id="ic_info" transform="translate(-7)">
+    <rect id="Rectangle_1604" data-name="Rectangle 1604" width="30" height="30" transform="translate(7)" fill="none"/>
+    <path id="Path_1931" data-name="Path 1931" d="M15,5A10,10,0,1,0,25,15,10,10,0,0,0,15,5Zm0,18.222A8.222,8.222,0,1,1,23.222,15,8.222,8.222,0,0,1,15,23.222ZM13.889,9.444A1.111,1.111,0,1,1,15,10.556,1.111,1.111,0,0,1,13.889,9.444Zm3.556,10.081v.585a.445.445,0,0,1-.445.445H13a.445.445,0,0,1-.445-.445v-.585a.445.445,0,0,1,.31-.424l.915-.29a.154.154,0,0,0,.108-.147V14.111h-.7A.635.635,0,0,1,13,12.871l2.533-.8a.445.445,0,0,1,.579.424v6.169a.154.154,0,0,0,.108.147l.915.29a.445.445,0,0,1,.31.424Z" transform="translate(7)" fill="#d51f5d"/>
+  </g>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/ic_search.svg b/CellFrameDashboardGUI/resources/icons/Certificates/ic_search.svg
new file mode 100644
index 0000000..77bb363
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/ic_search.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+  <g id="ic_search" transform="translate(-12.67 -12.17)">
+    <path id="Path_1930" data-name="Path 1930" d="M5.419,0a5.419,5.419,0,0,1,.4,10.824V17.05a.4.4,0,0,1-.793,0V10.824A5.419,5.419,0,0,1,5.419,0Zm0,.793a4.626,4.626,0,1,0,4.626,4.626A4.626,4.626,0,0,0,5.419.793Z" transform="translate(12.67 19.833) rotate(-45)" fill="#fff" fill-rule="evenodd"/>
+  </g>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/icon_arrow_down.svg b/CellFrameDashboardGUI/resources/icons/Certificates/icon_arrow_down.svg
new file mode 100644
index 0000000..b1f9aec
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/icon_arrow_down.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+  <g id="icon_arrow_down" transform="translate(24 24) rotate(180)">
+    <rect id="bg_arrow_down_icon" width="24" height="24" fill="none"/>
+    <path id="arrow_down_object_icon" d="M0,5,5,0l5,5Z" transform="translate(7 9)" fill="#505559"/>
+  </g>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates.svg b/CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates.svg
new file mode 100644
index 0000000..45c5129
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates.svg
@@ -0,0 +1,23 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="18" viewBox="0 0 19 18">
+  <g id="icon_certificates" transform="translate(-29 -117)">
+    <rect id="bg_icon" width="18" height="18" transform="translate(29 117)" fill="none"/>
+    <g id="Group_2131" data-name="Group 2131" transform="translate(-358 -237)">
+      <g id="Rectangle_1534" data-name="Rectangle 1534" transform="translate(387 354)" fill="#211a3a" stroke="#fff" stroke-width="1">
+        <rect width="15" height="18" rx="1" stroke="none"/>
+        <rect x="0.5" y="0.5" width="14" height="17" rx="0.5" fill="none"/>
+      </g>
+      <g id="Group_2346" data-name="Group 2346" transform="translate(0 -1.511)">
+        <path id="Path_1435" data-name="Path 1435" d="M-1663.591-801.045l-.158,6.847,2.057-2.2,1.819,2.2v-6.847Z" transform="translate(2063.168 1165.243)" fill="#211a3a" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+        <g id="Ellipse_5" data-name="Ellipse 5" transform="translate(397 357.511)" fill="#211a3a" stroke="#fff" stroke-width="1">
+          <circle cx="4.5" cy="4.5" r="4.5" stroke="none"/>
+          <circle cx="4.5" cy="4.5" r="4" fill="none"/>
+        </g>
+      </g>
+      <g id="Group_2131-2" data-name="Group 2131">
+        <line id="Line_38" data-name="Line 38" x2="5.478" transform="translate(390.022 358.5)" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="1"/>
+        <line id="Line_39" data-name="Line 39" x2="6.478" transform="translate(390.022 367.5)" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="1"/>
+        <path id="Path_1436" data-name="Path 1436" d="M0,0H5.709" transform="translate(390.022 362.5)" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="1"/>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates_hover.svg b/CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates_hover.svg
new file mode 100644
index 0000000..5bf19cd
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates_hover.svg
@@ -0,0 +1,23 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
+  <g id="icon_certificates_hover" transform="translate(-29 -117)">
+    <rect id="bg_icon" width="18" height="18" transform="translate(29 117)" fill="none"/>
+    <g id="Group_2131" data-name="Group 2131" transform="translate(-358 -237)">
+      <g id="Rectangle_1534" data-name="Rectangle 1534" transform="translate(387 354)" fill="#fff" stroke="#fff" stroke-width="1">
+        <rect width="15" height="18" rx="1" stroke="none"/>
+        <rect x="0.5" y="0.5" width="14" height="17" rx="0.5" fill="none"/>
+      </g>
+      <g id="Group_2346" data-name="Group 2346" transform="translate(0 0.989)">
+        <path id="Path_1435" data-name="Path 1435" d="M-1663.62-801.045l-.129,5.582,1.677-1.793,1.483,1.793v-5.582Z" transform="translate(2062.721 1164.008)" fill="#fff" stroke="#d51f5d" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
+      </g>
+      <g id="Group_2131-2" data-name="Group 2131">
+        <line id="Line_38" data-name="Line 38" x2="5.478" transform="translate(390.022 358.5)" fill="none" stroke="#d51f5d" stroke-linecap="round" stroke-width="1"/>
+        <line id="Line_39" data-name="Line 39" x2="6.478" transform="translate(390.022 367.5)" fill="none" stroke="#d51f5d" stroke-linecap="round" stroke-width="1"/>
+        <path id="Path_1436" data-name="Path 1436" d="M0,0H5.709" transform="translate(390.022 362.5)" fill="none" stroke="#d51f5d" stroke-linecap="round" stroke-width="1"/>
+      </g>
+      <g id="Ellipse_6" data-name="Ellipse 6" transform="translate(397 358)" fill="#fff" stroke="#d51f5d" stroke-width="1">
+        <circle cx="4" cy="4" r="4" stroke="none"/>
+        <circle cx="4" cy="4" r="3.5" fill="none"/>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/radio_off_dark.svg b/CellFrameDashboardGUI/resources/icons/Certificates/radio_off_dark.svg
new file mode 100644
index 0000000..c7ed55d
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/radio_off_dark.svg
@@ -0,0 +1,4 @@
+<svg id="radio_off_dark" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+  <rect id="rectangle" width="20" height="20" fill="none"/>
+  <path id="radio_off" d="M10.333,2a8.333,8.333,0,1,0,8.333,8.333A8.358,8.358,0,0,0,10.333,2Zm0,15A6.667,6.667,0,1,1,17,10.333,6.686,6.686,0,0,1,10.333,17Z" transform="translate(-0.333 -0.333)" fill="#211a3a" fill-rule="evenodd"/>
+</svg>
diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/radio_on_dark.svg b/CellFrameDashboardGUI/resources/icons/Certificates/radio_on_dark.svg
new file mode 100644
index 0000000..ed2664a
--- /dev/null
+++ b/CellFrameDashboardGUI/resources/icons/Certificates/radio_on_dark.svg
@@ -0,0 +1,4 @@
+<svg id="radio_on_dark" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+  <rect id="radio_on" width="20" height="20" fill="none"/>
+  <path id="radio_on-2" data-name="radio_on" d="M10.333,6.167A4.167,4.167,0,1,0,14.5,10.333a4.126,4.126,0,0,0-4.167-4.167Zm0-4.167a8.333,8.333,0,1,0,8.333,8.333A8.358,8.358,0,0,0,10.333,2Zm0,15A6.667,6.667,0,1,1,17,10.333,6.686,6.686,0,0,1,10.333,17Z" transform="translate(-0.333 -0.333)" fill="#211a3a" fill-rule="evenodd"/>
+</svg>
diff --git a/CellFrameDashboardGUI/screen/DapMainApplicationWindow.qml b/CellFrameDashboardGUI/screen/DapMainApplicationWindow.qml
index 39d4952..830b1e9 100644
--- a/CellFrameDashboardGUI/screen/DapMainApplicationWindow.qml
+++ b/CellFrameDashboardGUI/screen/DapMainApplicationWindow.qml
@@ -1,5 +1,7 @@
 import QtQuick 2.4
 import "qrc:/resources/QML"
+import "qrc:/screen/desktop/Certificates"
+
 
 DapMainApplicationWindowForm 
 {
@@ -17,13 +19,29 @@ DapMainApplicationWindowForm
     ///@detalis Path to the console tab.
     readonly property string consoleScreen: "qrc:/screen/" + device + "/Console/DapConsoleTab.qml"
 
+    ///@detalis Path to the console tab.
+    readonly property string certificatesScreen: "qrc:/screen/" + device + "/Certificates/DapCertificatesMainPage.qml"
+
     ///@details dapMainFonts Project font loader
     readonly property QtObject dapMainFonts: DapFontRoboto {}
+    //readonly property DapFontQuicksand quicksandFonts:
+    DapFontQuicksand {
+        id: quicksandFonts
+    }
+
+
 
     property var dapWallets: []
 
     signal modelWalletsUpdated()
 
+
+    //open in module visible root context, only for work
+    Component{
+        DapCertificatesMainPage { }
+    }
+
+
     ListModel
     {
         id: dapNetworkModel
@@ -62,6 +80,15 @@ DapMainApplicationWindowForm
                 hoverIcon: "qrc:/resources/icons/icon_history_hover.png"
             })
 
+
+            append ({
+                name: qsTr("Certificates"),
+                page: certificatesScreen,
+                normalIcon: "qrc:/resources/icons/Certificates/icon_certificates.svg",
+                hoverIcon: "qrc:/resources/icons/Certificates/icon_certificates_hover.svg"
+            })
+
+
             append ({
                 name: qsTr("Console"),
                 page: consoleScreen,
@@ -103,10 +130,13 @@ DapMainApplicationWindowForm
         target: dapServiceController
         onNetworksListReceived:
         {
+            if (!networkList)
+                console.error("networkList is empty")
+
             for(var n=0; n < Object.keys(networkList).length; ++n)
             {
                 dapServiceController.CurrentNetwork = networkList[0];
-                dapServiceController.IndexCurrentNetwork = 0;
+                dapServiceController.IndexCurrentNetwork = 0;                //тут разве не должно быть n? или этой строки вообще недолжно быть тут. А если список сетей пуст?
                 dapNetworkModel.append({name: networkList[n]})
             }
         }
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CertificateInfoItem.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificateInfoItem.qml
new file mode 100644
index 0000000..b6324b0
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificateInfoItem.qml
@@ -0,0 +1,79 @@
+import QtQuick 2.9
+import "qrc:/widgets"
+import "parts"
+
+
+
+
+Rectangle {
+    id: root
+    property alias closeButton: closeButton
+    property alias certificateDataListView: certificateDataListView
+
+    implicitWidth: 100
+    implicitHeight: 200
+
+    border.color: "#E2E1E6"
+    border.width: 1 * pt
+    radius: 8 * pt
+    color: "transparent"
+
+    //part animation on created and open
+    visible: false
+    opacity: visible ? 1.0 : 0.0
+    Behavior on opacity {
+        NumberAnimation {
+            duration: 100
+            easing.type: Easing.InOutQuad
+        }
+    }
+
+
+    Item {
+        id: titleRectangle
+        width: parent.width
+        height: 40 * pt
+
+        CloseButton {
+            id: closeButton
+            x: 16 * pt
+        }  //
+
+
+        Text {
+            id: certificatesTitleText
+            anchors{
+                left: closeButton.right
+                leftMargin: 18 * pt
+                verticalCenter: closeButton.verticalCenter
+            }
+            font: quicksandFonts.bold14
+            color: "#3E3853"
+            text: qsTr("Info about certificate")
+        }
+    }  //titleRectangle
+
+
+    ListView {
+        id: certificateDataListView
+        y: titleRectangle.y + titleRectangle.height + 26 * pt
+        width: parent.width
+        height: contentHeight
+        spacing: 22 * pt
+        clip: true
+
+        delegate: TitleTextView {
+            x: 20 * pt
+            title.text: model.keyView
+            content.text: model.value
+        }
+    }
+
+
+
+
+
+}   //root
+
+
+
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesActionsButtonList.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesActionsButtonList.qml
new file mode 100644
index 0000000..a267d84
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesActionsButtonList.qml
@@ -0,0 +1,232 @@
+import QtQuick 2.9
+import QtQuick.Layouts 1.2
+import QtQuick.Controls 2.2
+import "qrc:/widgets"
+
+
+
+
+Item {
+    id: root
+
+    signal selectedAccessKeyType(int index)
+
+    property alias certificateAccessTypeRepeater: certificateAccessTypeRepeater
+
+    property alias createCertificateButton: createCertificateButton
+    property alias importCertificateButton: importCertificateButton
+    property alias exportPublicCertificateToFileButton: exportPublicCertificateToFileButton
+    property alias exportPublicCertificateToMempoolButton: exportPublicCertificateToMempoolButton
+    property alias addSignatureToCertificateButton: addSignatureToCertificateButton
+    property alias deleteCertificateButton: deleteCertificateButton
+
+    property bool certificateSelected: false
+    property bool bothAccessTypeCertificateSelected: false
+
+    implicitWidth: 270 * pt
+    implicitHeight: 166 * pt
+
+    //part animation on created and open
+    visible: false
+    opacity: visible ? 1.0 : 0.0
+    Behavior on opacity {
+        NumberAnimation {
+            duration: 100
+            easing.type: Easing.InOutQuad
+        }
+    }
+
+    function setAccessTypeSeletedIndex(index) {
+            //TODO выделять нужную кнопку
+    }
+
+
+    ButtonGroup {
+        id: buttonGroup
+    }
+
+
+    Item {
+        id: radioButtonFrame
+        y: 12 * pt
+        width: parent.width - x
+        height: 166 * pt
+
+        Text {
+            id: filterTitleText
+            x: 15 * pt
+            font: quicksandFonts.bold14
+            color: "#3E3853"
+            text: qsTr("Filter")
+        }
+
+        ColumnLayout {
+            id: certificateAccessTypeLayout
+            spacing: 35 * pt
+            y: filterTitleText.y + filterTitleText.height + 24 * pt
+            x: 15 * pt
+            width: parent.width - x
+
+            Repeater {
+                id: certificateAccessTypeRepeater
+
+                DapRadioButton {    //qrc:/screen/desktop/Certificates/CertificatesActionsButtonList.qml:73:17: QML DapRadioButtonForm.ui: Binding loop detected for property "baselineOffset"
+                    id: buttonSelectionNothing
+                    nameRadioButton: model.name
+                    Layout.preferredHeight: 16 * pt
+                    Layout.fillWidth: true
+                    indicatorSize: 16 * pt
+                    indicatorInnerSize: 7 * pt
+                    spaceIndicatorText: 18 * pt
+                    fontRadioButton: quicksandFonts.regular16
+                    indicatorBackgroundColor: "transparent"
+                    indicatorBorder.width: 2 * pt
+                    indicatorBorderColor: "#211A3A"
+                    indicatorInnerColorActiv: "#211A3A"
+                    indicatorInnerColorNormal: "transparent"
+                    nameTextColor: "#070023"
+                    ButtonGroup.group: buttonGroup
+                    checked: model.selected
+                    onClicked: {
+                        root.selectedAccessKeyType(model.index)
+                    }
+                }  //
+            }  //
+        }  //
+    }  //radioButtonFrame
+
+
+    Text {
+        id: actionsTitleText
+        x: 15 * pt
+        y: radioButtonFrame.y + radioButtonFrame.height + 44 * pt
+        font: quicksandFonts.bold14
+        color: "#3E3853"
+        text: qsTr("Actions")
+    }
+
+
+    ColumnLayout {
+        id: actionButtonsLayout
+        spacing: 24 * pt
+        y: actionsTitleText.y + actionsTitleText.height + 24 * pt
+        width: parent.width
+
+        DapButton {
+            id: createCertificateButton
+            textButton: qsTr("Create certificate")
+            Layout.fillWidth: true
+            Layout.preferredHeight: 36 * pt
+
+            colorBackgroundNormal: "#271C4E"
+            colorBackgroundHover: "#D2145D"
+            colorButtonTextNormal: "#FFFFFF"
+            colorButtonTextHover: "#FFFFFF"
+            borderColorButton: "#000000"
+            borderWidthButton: 0
+            radius: 4 * pt
+            fontButton: quicksandFonts.regular16
+            horizontalAligmentText: Qt.AlignHCenter
+        }
+
+        DapButton {
+            id: importCertificateButton
+            textButton: qsTr("Import certificate")
+            Layout.fillWidth: true
+            Layout.preferredHeight: 36 * pt
+            visible: false   //TODO need clarification of the requirements
+
+            colorBackgroundNormal: "#271C4E"
+            colorBackgroundHover: "#D2145D"
+            colorButtonTextNormal: "#FFFFFF"
+            colorButtonTextHover: "#FFFFFF"
+            borderColorButton: "#000000"
+            borderWidthButton: 0
+            radius: 4 * pt
+            fontButton: quicksandFonts.regular16
+            horizontalAligmentText: Qt.AlignHCenter
+        }
+
+
+        DapButton {
+            id: exportPublicCertificateToFileButton
+            textButton: qsTr("Export public certificate to file")
+            Layout.fillWidth: true
+            Layout.preferredHeight: 36 * pt
+
+            enabled: root.certificateSelected && bothAccessTypeCertificateSelected
+            colorBackgroundNormal: enabled ? "#271C4E" : "white"
+            colorBackgroundHover: enabled ? "#D2145D" : "white"
+            colorButtonTextNormal: enabled ? "#FFFFFF" : "#211A3A"
+            colorButtonTextHover: enabled ? "#FFFFFF" : "#211A3A"
+            borderColorButton: enabled ? "#000000" : "#211A3A"
+            borderWidthButton: enabled ? 0 : (1 * pt)
+            radius: 4 * pt
+            fontButton: quicksandFonts.regular16
+            horizontalAligmentText: Qt.AlignHCenter
+        }
+
+
+        DapButton {
+            id: exportPublicCertificateToMempoolButton
+            textButton: qsTr("Export public certificate to mempool")
+            Layout.fillWidth: true
+            Layout.preferredHeight: 36 * pt
+
+            enabled: root.certificateSelected
+            colorBackgroundNormal: enabled ? "#271C4E" : "white"
+            colorBackgroundHover: enabled ? "#D2145D" : "white"
+            colorButtonTextNormal: enabled ? "#FFFFFF" : "#211A3A"
+            colorButtonTextHover: enabled ? "#FFFFFF" : "#211A3A"
+            borderColorButton: enabled ? "#000000" : "#211A3A"
+            borderWidthButton: enabled ? 0 : (1 * pt)
+            radius: 4 * pt
+            fontButton: quicksandFonts.regular16
+            horizontalAligmentText: Qt.AlignHCenter
+        }
+
+
+        DapButton {
+            id: addSignatureToCertificateButton
+            textButton: qsTr("Add signature to certificate")
+            Layout.fillWidth: true
+            Layout.preferredHeight: 36 * pt
+            visible: false   //TODO need clarification of the requirements
+
+            enabled: root.certificateSelected
+            colorBackgroundNormal: enabled ? "#271C4E" : "white"
+            colorBackgroundHover: enabled ? "#D2145D" : "white"
+            colorButtonTextNormal: enabled ? "#FFFFFF" : "#211A3A"
+            colorButtonTextHover: enabled ? "#FFFFFF" : "#211A3A"
+            borderColorButton: enabled ? "#000000" : "#211A3A"
+            borderWidthButton: enabled ? 0 : (1 * pt)
+            radius: 4 * pt
+            fontButton: quicksandFonts.regular16
+            horizontalAligmentText: Qt.AlignHCenter
+        }
+
+        DapButton {
+            id: deleteCertificateButton
+            textButton: qsTr("Delete certificate")
+            Layout.fillWidth: true
+            Layout.preferredHeight: 36 * pt
+
+            enabled: root.certificateSelected
+            colorBackgroundNormal: enabled ? "#271C4E" : "white"
+            colorBackgroundHover: enabled ? "#D2145D" : "white"
+            colorButtonTextNormal: enabled ? "#FFFFFF" : "#211A3A"
+            colorButtonTextHover: enabled ? "#FFFFFF" : "#211A3A"
+            borderColorButton: enabled ? "#000000" : "#211A3A"
+            borderWidthButton: enabled ? 0 : (1 * pt)
+            radius: 4 * pt
+            fontButton: quicksandFonts.regular16
+            horizontalAligmentText: Qt.AlignHCenter
+        }
+
+
+    }   //actionButtonsLayout
+
+
+
+
+}  //root
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesListView.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesListView.qml
new file mode 100644
index 0000000..74df2d9
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesListView.qml
@@ -0,0 +1,169 @@
+import QtQuick 2.9
+import "parts"
+
+
+
+ListView {
+    id: root
+    property alias delegateComponent: delegateComponent
+    signal selectedIndex(int index)
+    signal infoClicked(int index)
+
+    property string seletedCertificateAccessType: qsTr("Public")
+    property bool infoTitleTextVisible: false
+
+
+    //interactive: contentHeight > height
+    headerPositioning: ListView.OverlayHeader
+    spacing: 14 * pt
+    clip: true
+
+
+    header: Item {
+        width: parent.width
+        height: certificatesTitle.height + tableTitle.height + spacing
+        z: 10
+
+        Rectangle {
+            id: certificatesTitle
+            width: parent.width
+            height: 40 * pt
+
+            Text {
+                id: certificatesTitleText
+                x: 15 * pt
+                height: parent.height
+                verticalAlignment: Text.AlignVCenter
+                font: quicksandFonts.bold14
+                color: "#3E3853"
+                text: qsTr("Certificates")
+            }
+        }
+
+
+        Rectangle {
+            id: tableTitle
+            width: parent.width
+            height: 30 * pt
+            y: 40 * pt
+            color: "#3E3853"
+
+            Text {
+                x: 15 * pt
+                height: parent.height
+                verticalAlignment: Text.AlignVCenter
+                font: quicksandFonts.medium11
+                text: root.seletedCertificateAccessType
+                color: "white"
+            }
+
+            Text {
+                id: infoTitleText
+                x: 15 * pt
+                anchors {
+                    right: parent.right
+                    rightMargin: 21 * pt
+                }
+                height: parent.height
+                verticalAlignment: Text.AlignVCenter
+                font: quicksandFonts.medium11
+                text: qsTr("Info")
+                visible: root.infoTitleTextVisible
+                color: "white"
+            }
+        }
+
+    }  //header
+
+
+    Component {
+        id: delegateComponent
+
+        Item {
+            //this property need set from root
+            width: root.width
+            height: 40 * pt
+
+            Text {
+                id: certificateNameText
+                x: 14 * pt
+                width: 612 * pt
+                height: parent.height
+                verticalAlignment: Text.AlignVCenter
+                font: model.selected ? quicksandFonts.mediumBold16 : quicksandFonts.regular16
+                text: model.completeBaseName   //model.fileName
+                color: model.selected ? "#D51F5D" : "#070023"
+                elide: Text.ElideRight
+                maximumLineCount: 1
+            }
+
+
+            MouseArea{
+                id: delegateClicked
+                width: parent.width
+                height: parent.height
+                onClicked: {
+                    root.selectedIndex(model.index)
+                }
+
+                onDoubleClicked: {
+                    root.infoClicked(model.index)
+                    //root.selectedIndex(model.index)
+                }
+            }
+
+
+            ToolButton {
+                id: infoButton
+                anchors {
+                    left: certificateNameText.right
+                    right: parent.right
+                }
+                height: parent.height
+                visible: model.selected
+
+                image.anchors {
+                    right: infoButton.right
+                    rightMargin: 14 * pt
+                }
+                image.source: "qrc:/resources/icons/Certificates/ic_info.svg"
+                image.width: 30 * pt
+                image.height: 30 * pt
+
+                onClicked: {
+                    root.infoClicked(model.index)
+                }
+
+            }  //
+
+
+            Rectangle {
+                id: bottomLine
+                x: certificateNameText.x
+                y: parent.height
+                width: 648 * pt
+                height: 1 * pt
+                color: "#E3E2E6"
+            }
+
+        }  //
+
+    }  //delegateComponent
+
+
+
+    Rectangle {  //border frame
+        width: parent.width
+        height: parent.height
+        border.color: "#E2E1E6"
+        border.width: 1 * pt
+        radius: 8 * pt
+        color: "transparent"
+        z: 1
+    }
+
+
+
+
+
+}  //root
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesLogic.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesLogic.qml
new file mode 100644
index 0000000..41c199e
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesLogic.qml
@@ -0,0 +1,288 @@
+import QtQuick 2.0
+import DapCertificateManager.Commands 1.0
+
+
+/*
+      reply from service format
+      result = {
+                    command: <enumcommand>
+                    status: "OK" | "FAIL",
+                    errorMessage: "",            //optional when error
+                    data: ...                    //empty or object or array
+               }
+*/
+
+
+
+Item {
+    id: root
+
+    //сигнализирует о выполнении запроса когда запущен реквест
+    property bool requestRunning: false
+
+
+    Component.onCompleted: {
+        dapServiceController.requestToService(DapCertificateCommands.serviceName
+                                              , DapCertificateCommands.GetSertificateList
+                                              );
+    }
+
+
+
+    Connections
+    {
+        target: dapServiceController
+
+        onCertificateManagerOperationResult: {   //const QVariant& result
+            if (!result) {
+                console.error("result is empty")
+                return
+            }
+
+            utils.beatifulerJSONKeys(result, "onCertificateManagerOperationResult");    //for test
+            //messagePopup.smartOpen("Certificate", "result.errorMessage")
+
+            requestRunning = false
+
+            //common error message box
+            if (result.status !== DapCertificateCommands.statusOK) {
+                console.error("execute command %1, message %2"
+                              .arg(DapCertificateCommands.commandToString(result.command)).arg(result.errorMessage))
+                messagePopup.smartOpen(qsTr("Certificate"), result.errorMessage)
+            }
+
+
+            switch (result.command) {
+                case DapCertificateCommands.UnknownCommand:    //0
+                    console.warn("DapCertificateCommands.UnknownCommand")
+                    break;
+                case DapCertificateCommands.GetSertificateList:
+                    if (!Array.isArray(result.data)) {
+                        console.error("result.data not array")
+                        return
+                    }
+
+                    if (result.status === DapCertificateCommands.statusOK) {
+                        models.certificates.parseFromCertList(result.data)
+                    }
+
+                    break;
+                case DapCertificateCommands.CreateCertificate:
+                    if (!(typeof result.data === "object")) {
+                        console.error("result.data not object")
+                        return
+                    }
+                    //utils.beatifulerJSON(result.data, "DapCertificateCommands.CreateCertificate")   //for test
+                    if (result.status === DapCertificateCommands.statusOK) {
+                        models.certificates.prependFromObject(result.data)
+                        models.certificates.clearSelected()
+                        rightPanel.sourceComponent = createFinishedItemComponent
+                    }
+                    break;
+                case DapCertificateCommands.DumpCertifiacate:
+                    //utils.beatifulerJSON(result, "DapCertificateCommands.DumpCertifiacate");    //for test
+                    if (result.status === DapCertificateCommands.statusOK) {
+                        models.certificateInfo.clear()
+
+                        models.certificateInfo.append({   key: "signature",
+                                                          keyView: qsTr("Signature type")
+                                                        , value: models.signatureKeyToViewName[result.data.signature] } )
+                        models.certificateInfo.append({   key: "name",
+                                                          keyView: qsTr("Title")
+                                                        , value: result.data.name } )
+
+                        for (var i in result.data.metadata) {
+                            var metadataElement = result.data.metadata[i]
+//                            switch (metadataElement.key) {      //date format
+//                                case "creation_date":
+//                                case "expiration_date": {
+//                                      //TODO need save date to ISO
+//                                    metadataElement.value = Qt.formatDate(new Date(metadataElement.value, '.', '-'), "dd MMM, yyyy")
+//                                    }
+//                                    break;
+//                            }
+
+                            var keyView = models.metadataKeyToViewKey[metadataElement.key]
+                             models.certificateInfo.append({
+                                                                 key: metadataElement.key
+                                                               , keyView: keyView ? keyView : metadataElement.key
+                                                               , value: metadataElement.value
+                                                           })
+                        }
+                    }
+                    break;
+                case DapCertificateCommands.ImportCertificate:
+                    //TODO
+                    break;
+                case DapCertificateCommands.ExportPublicCertificateToFile:
+                    //utils.beatifulerJSON(result.data, "DapCertificateCommands.ExportPublicCertificateToFile")   //for test
+                    if (!(typeof result.data === "object")) {
+                        console.error("result.data not object")
+                        return
+                    }
+                    if (result.status === DapCertificateCommands.statusOK) {
+                        models.certificates.clearSelected()
+                        models.certificates.prependFromObject(result.data)
+                        messagePopup.smartOpen(qsTr("Certificate"), "Public certificate created, file path:\n%1".arg(result.data.filePath))
+                    }
+
+                    break;
+                case DapCertificateCommands.ExportPublicCertificateToMempool:
+                    //utils.beatifulerJSON(result, "DapCertificateCommands.ExportPublicCertificateToMempool")     //for test
+
+                    if (!(typeof result.data === "object")) {
+                        console.error("result.data not object")
+                        return
+                    }
+
+                    if (result.status === DapCertificateCommands.statusOK) {
+                        messagePopup.smartOpen(qsTr("Certificate"), "Success export to mempool\ncertificate: %1\nnetwork: %2"
+                                               .arg(result.data.certName).arg(result.data.network))
+                    }
+
+                    break;
+                case DapCertificateCommands.AddSignatureToCertificate:
+                    //TODO
+                    break;
+                case DapCertificateCommands.DeleteCertificate:
+                    //utils.beatifulerJSON(result.data, "DapCertificateCommands.DeleteCertificate");    //for test                   
+                    if (result.status === DapCertificateCommands.statusOK) {
+                        messagePopup.smartOpen(qsTr("Certificate"), qsTr("Certificate deleted\n%1").arg(result.data.deletedFilePath))
+                        models.certificates.removeByProperty("filePath", result.data.deletedFilePath)
+                        models.certificates.clearSelected()
+                        return
+                    }
+                    break;
+
+                    //пока что неиспользуемый сценарий
+                case DapCertificateCommands.UpdateCertificateList:    //уведомление только если изменяется папка сертификатов вручную
+                    if (!Array.isArray(result.data)) {
+                        console.error("result.data not array")
+                        return
+                    }
+                    if (result.status === DapCertificateCommands.statusOK) {
+                        models.certificates.parseFromCertList(result.data)
+                    }
+
+                    break;
+                default:
+                    console.error("onCertificateManagerOperationResult not valid command")
+                    break;
+            }   //switch
+
+        }   //onCertificateManagerOperationResult:
+
+
+    }   //target: dapServiceController
+
+
+   //format "id", "fileName", "completeBaseName", "filePath", "dirType", "accessKeyType"
+
+    function createCertificate(certName, certType, metaData){     //metaData  is array of { type, , value }
+        console.info("FLOWPOINT createCertificate", certName, certType)
+
+        dapServiceController.requestToService(DapCertificateCommands.serviceName
+                                              , DapCertificateCommands.CreateCertificate
+                                              , certName, certType
+                                              , JSON.stringify(metaData));
+    }
+
+
+    //получение информации о сертификате
+    function dumpCertificate(index){
+        var cert = models.certificates.get(index)
+        console.info("FLOWPOINT dumpCertificate, index", index)
+
+        if (cert) {
+            dapServiceController.requestToService(DapCertificateCommands.serviceName
+                                                  , DapCertificateCommands.DumpCertifiacate
+                                                  , cert.completeBaseName, cert.filePath);   //completeBaseName
+        } else
+            console.error("not valid index", index)
+    }
+
+
+    function exportPublicCertificateToFile(index){     //index from certificates model
+        var cert = models.certificates.get(index)
+        console.info("FLOWPOINT exportPublicCertificateToFile")
+
+        if (cert) {
+            var certName = cert.completeBaseName
+            dapServiceController.requestToService(DapCertificateCommands.serviceName
+                                                  , DapCertificateCommands.ExportPublicCertificateToFile
+                                                  , certName, certName + "_public" );
+        } else
+            console.error("not valid index", index)
+    }
+
+
+    function exportPublicCertificateToMempool(index){     //index from certificates model
+        var cert = models.certificates.get(index)
+        console.info("FLOWPOINT exportPublicCertificateToMempool, index", index)
+
+        if (cert && dapServiceController.CurrentNetwork !== "") {
+            requestRunning = true           //долгий запрос, требует индикации
+            dapServiceController.requestToService(DapCertificateCommands.serviceName
+                                                  , DapCertificateCommands.ExportPublicCertificateToMempool
+                                                  , dapServiceController.CurrentNetwork, cert.completeBaseName);
+        } else
+            console.error("not valid index or network", index, dapServiceController.CurrentNetwork)
+    }
+
+
+
+    function deleteCertificate(index){     //index from certificates model
+        var cert = models.certificates.get(index)
+        console.info("FLOWPOINT deleteCertificate, index", index)
+
+        if (cert)
+            dapServiceController.requestToService(DapCertificateCommands.serviceName
+                                                  , DapCertificateCommands.DeleteCertificate
+                                                  , cert.filePath);
+        else
+            console.error("not valid index", index)         //
+    }
+
+
+    //TODO Import certificate
+    //TODO Add signature to certificate
+
+
+
+}  //root
+
+
+
+/* simple stress test rpc
+
+
+    property int count: 10000
+    property int calcCount: 0
+    property var commandQueue: []
+
+
+    Component.onCompleted: {
+        for (var i = 0; i < count; ++i) {
+            var comand =  Math.floor(Math.random() * 10000 % DapCertificateCommands.UpdateCertificateList)
+            //console.info("send comand:", comand)
+            commandQueue.push(comand)
+
+            dapServiceController.requestToService(DapCertificateCommands.serviceName
+                                                  , comand);
+        }
+    }
+
+
+    Connections
+    {
+        target: dapServiceController
+        onCertificateManagerOperationResult: {   //const QVariant& result
+            if (commandQueue[root.calcCount] === comand)
+                calcCount++
+            if (root.count === root.calcCount)
+                console.info("stress test success")
+        }
+
+    }   //target: dapServiceController
+
+*/
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesMainPage.qml.autosave b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesMainPage.qml.autosave
new file mode 100644
index 0000000..e2d023f
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesMainPage.qml.autosave
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+import QtQuick.Controls 2.0
+
+
+Rectangle 
+{
+//    id: frameScreen
+
+//    ///@detalis Frame widget.
+//    property alias dapFrame: frameScreen
+//    ///@detalis Screen components.
+//    property Item dapContenetItemScreen
+
+//    anchors.fill: parent
+
+//    // Install screen components
+//    Item 
+//    {
+//        id: contenetItemScreen
+//        data: dapContenetItemScreen
+//        anchors.fill: parent
+//    }
+}
\ No newline at end of file
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesModels.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesModels.qml
new file mode 100644
index 0000000..e59fcb8
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesModels.qml
@@ -0,0 +1,198 @@
+import QtQuick 2.0
+import DapCertificateManager.Commands 1.0
+import "parts"
+import "models"
+
+
+
+Item {
+    id: root
+    property alias accessKeyType: accessKeyType
+    property alias certificates: certificates
+    property alias certificatesFind: certificatesFind
+    property alias certificateInfo: certificateInfo
+
+    property alias signatureType: signatureType
+    property alias createCertificateOptional: createCertificateOptional
+
+
+    readonly property var signatureKeyToViewName: ({
+                                               "sig_dil": qsTr("Crystal-Dylithium"),
+                                               "sig_bliss": qsTr("Bliss"),
+                                               "sig_picnic": qsTr("Picnic"),
+                                               "sig_tesla": qsTr("Tesla")
+                                           })
+
+
+    readonly property var metadataKeyToViewKey: ({
+                                               "creation_date": qsTr("Date of creation"),
+                                               "expiration_date": qsTr("Expiration date"),
+                                               "domain": qsTr("Domain"),
+                                               "organization": qsTr("Organization"),
+                                               "fullname": qsTr("Full name"),
+                                               "email": qsTr("Email"),
+                                               "description": qsTr("Description")
+                                           })
+
+
+    ListModel {
+        id: accessKeyType
+        property int selectedIndex: 0
+        //selected certificate with private and public key
+        readonly property bool bothTypeCertificateSelected: selectedIndex === 2
+
+        ListElement { name: qsTr("Public certificates"); type: "public"; selected: true }
+        ListElement { name: qsTr("Private certificates"); type: "private"; selected: false }
+        ListElement { name: qsTr("Both"); type: "both"; selected: false }
+
+        function setSelectedIndex(index){
+            selectedIndex = index
+            for (var i = 0; i < count; ++i)
+                 setProperty(i, "selected", index === i)
+        }
+    }
+
+
+    ListModel {
+        id: certificateInfo
+        //format key, keyView, value
+        //keys: [certName, certSignatureType]     -  required
+        //      [creation_date, domain, expiration_date, organization, fullname, email, description]   - optional
+
+    }
+
+
+    ListModel {
+        id: createCertificateOptional
+        //вообще эти ключи нужно вынести в общее перечисление
+        //creation_date default key
+        ListElement { placeHolderText: qsTr("Domain"); key: "domain"; data: ""; inputFieldMask: "";  }
+        ListElement { placeHolderText: qsTr("Expiration date"); key: "expiration_date"; data: ""; inputFieldMask: "99.99.9999"; }
+        ListElement { placeHolderText: qsTr("Organization"); key: "organization"; data: ""; inputFieldMask: ""; }
+        ListElement { placeHolderText: qsTr("Full name"); key: "fullname"; data: ""; inputFieldMask: ""; }
+        ListElement { placeHolderText: qsTr("Email"); key: "email"; data: ""; inputFieldMask: ""; }
+        ListElement { placeHolderText: qsTr("Description"); key: "description"; data: ""; inputFieldMask: ""; }
+
+        function dataClear(){
+            for (var i = 0; i < count; ++i)
+                setProperty(i, "data", "")
+        }
+
+        function getDataToJson(){
+            var result = { creation_date: Qt.formatDateTime(new Date(), "dd.MM.yyyy") }
+            for (var i = 0; i < count; ++i) {
+                var item = get(i)
+                if (item.data !== "") {
+                    result[item.key] = item.data
+                }
+            }
+
+            return result
+        }
+    }  //createCertificateOptional
+
+
+
+    ListModel {        //this common model
+        id: signatureType
+        ListElement {  name: "Crystal-Dylithium"; signature: "sig_dil"; isRecomended: true  }
+        ListElement {  name: "Bliss"; signature: "sig_bliss"; isRecomended: false  }
+        ListElement {  name: "Picnic"; signature: "sig_picnic"; isRecomended: false  }
+        ListElement {  name: "Tesla"; signature: "sig_tesla"; isRecomended: false  }
+    }
+
+
+    ListModel {
+        id: certificates
+        //format "fileName", "completeBaseName", "filePath", "dirType", "accessKeyType"
+
+        property int selectedIndex: -1
+        readonly property bool isSelected: selectedIndex >= 0
+
+        function prependFromObject(obj) {
+            obj.selected = false
+            insert(0, obj)
+        }
+
+        function appendFromObject(obj) {
+            obj.selected = false
+            append(obj)
+        }
+
+        function clearSelected() {
+            if (selectedIndex >= 0) {
+                setProperty(selectedIndex, "selected", false)
+                selectedIndex = -1
+            }
+        }
+
+        function setSelectedIndex(index){
+            selectedIndex = index
+            for (var i = 0; i < count; ++i)
+                 setProperty(i, "selected", index === i)
+        }
+
+        function parseFromCertList(certList){
+            clearSelected()
+            clear()
+            for (var i = 0; i < certList.length; ++i) {
+                certList[i].selected = false
+                //utils.beatifulerJSON(certList[i], "certList[%1]".arg(i))  //for test
+                append(certList[i])
+            }
+        }
+
+
+        function removeByProperty(propertyName, value){
+            for (var i = 0; i < count; ++i) {
+                var item = get(i)
+                if (item && typeof item[propertyName] !== "undefined")
+                     if (item[propertyName] === value) {
+                         remove(i)
+                         return true
+                     }
+            }
+            return false
+        }
+
+    }  //certificates
+
+
+    //find over certificate model
+    FindDelegateModel {
+        id: certificatesFind
+        model: certificates
+
+        property string findString: ""
+        property int accessKeyTypeIndex: 0            //from DapCertificateType::accessKeyType
+
+        function update() {
+            //console.info("update()", accessKeyTypeIndex, findString, items.count)
+            if (findString !== "") {                             //find by name and accessKeyTypeIndex
+                var fstr = findString.toLocaleLowerCase()
+
+                predicate = function (obj) {
+                    return obj.fileName.toLowerCase().indexOf(fstr) >= 0
+                           && obj.accessKeyType === accessKeyTypeIndex
+                }
+                renew()
+                return;
+            } else {                                            //find only by accessKeyTypeIndex
+                predicate = function (obj) {
+                    return  obj.accessKeyType === accessKeyTypeIndex
+                }
+                renew()
+                return;
+            }
+
+            //without find -> all items visible in view
+            //   predicate = function(obj) { return true; }
+            //   renew()
+
+        }  //update
+
+    }  //certificatesFind
+
+
+
+}  //
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CreateCertificateItem.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CreateCertificateItem.qml
new file mode 100644
index 0000000..49d2632
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CreateCertificateItem.qml
@@ -0,0 +1,232 @@
+import QtQuick 2.9
+import QtQuick.Layouts 1.2
+import QtQuick.Controls 2.2
+import "qrc:/widgets"
+import "parts"
+
+
+
+
+Rectangle {
+    id: root
+    property alias closeButton: closeButton
+    property alias createButton: createButton
+    property alias optionalModel: optionalRepeater.model
+    property alias signatureTypeCertificateComboBox: signatureTypeCertificateComboBox
+    property alias titleCertificateTextInput: titleCertificateTextInput
+
+    property bool requiredFieldValid: false
+
+    implicitWidth: 100
+    implicitHeight: 200
+
+    border.color: "#E2E1E6"
+    border.width: 1 * pt
+    radius: 8 * pt
+    color: "transparent"
+
+    //part animation on created and open
+    visible: false
+    opacity: visible ? 1.0 : 0.0
+    Behavior on opacity {
+        NumberAnimation {
+            duration: 100
+            easing.type: Easing.InOutQuad
+        }
+    }
+
+
+    Item {
+        id: titleRectangle
+        width: parent.width
+        height: 40 * pt
+
+        CloseButton {
+            id: closeButton
+        }
+
+        Text {
+            id: certificateTitleText
+            anchors{
+                left: closeButton.right
+                leftMargin: 18 * pt
+                verticalCenter: closeButton.verticalCenter
+            }
+            font: quicksandFonts.bold14
+            color: "#3E3853"
+            text: qsTr("Create certificate")
+        }
+    }  //titleRectangle
+
+
+    Rectangle {
+        id: requiredTitle
+        width: parent.width
+        height: 30 * pt
+        y: 38 * pt
+        color: "#3E3853"
+
+        Text {
+            x: 15 * pt
+            height: parent.height
+            verticalAlignment: Text.AlignVCenter
+            font: quicksandFonts.medium11
+            text: qsTr("Required")
+            color: "white"
+        }
+
+    }
+
+
+    Item {
+        id: requiredBody
+        y: requiredTitle.y + requiredTitle.height
+        width: parent.width
+        height: 138 * pt
+
+        DapComboBox {
+            id: signatureTypeCertificateComboBox
+            // x: popup.visible ? sidePaddingActive * (-1) : sidePaddingNormal    //???
+
+            anchors.verticalCenter: undefined
+            x: (parent.width - width) / 2
+            y: 13 * pt
+            widthPopupComboBoxNormal: 280 * pt
+            widthPopupComboBoxActive: 313 * pt
+            heightComboBoxNormal: 32 * pt
+            heightComboBoxActive: 42 * pt
+
+            comboBoxTextRole: ["name"]
+            mainLineText: qsTr("Signature type")
+            indicatorImageNormal: "qrc:/resources/icons/Certificates/icon_arrow_down.svg"  //"qrc:/resources/icons/ic_arrow_drop_down_dark.png"
+            indicatorImageActive: "qrc:/resources/icons/Certificates/ic_arrow_up.svg"   //qrc:/resources/icons/ic_arrow_drop_up.png"
+            sidePaddingNormal: 0 * pt
+            sidePaddingActive: 20 * pt
+            bottomIntervalListElement: 8 * pt
+            paddingTopItemDelegate: 8 * pt
+            heightListElement: 42 * pt
+            //intervalListElement: 10 * pt
+            indicatorWidth: 24 * pt
+            indicatorHeight: indicatorWidth
+            indicatorLeftInterval: 20 * pt
+
+            normalColorText: "#070023"      //#B4B1B placeholder color
+            hilightColorText: "#FFFFFF"
+            normalColorTopText: "#070023"
+            hilightColorTopText: "#070023"
+            hilightColor: "#D51F5D"   //"#330F54"
+            normalTopColor: "transparent"
+            topEffect: false
+            normalColor: "#FFFFFF"
+            hilightTopColor: normalColor
+            colorTopNormalDropShadow: "#00000000"
+            colorDropShadow: "#40ABABAB"
+            fontComboBox: [quicksandFonts.regular16]
+            colorMainTextComboBox: [["#070023", "#070023"]]
+            colorTextComboBox: [["#070023", "#FFFFFF"]]
+        }
+
+
+        InputField {
+            id: titleCertificateTextInput
+            x: (parent.width - width) / 2
+            y: 78 * pt
+            height: 28 * pt
+            width: 277 * pt
+            leftPadding: 0
+            smartPlaceHolderText: qsTr("Title")
+            color: focus ? "#D51F5D" : "#070023"
+            font: quicksandFonts.regular16
+        }
+
+
+    }  //requiredBody
+
+
+    Rectangle {
+        id: optionalTitle
+        width: parent.width
+        height: 30 * pt
+        y: requiredBody.y + requiredBody.height
+        color: "#3E3853"
+
+        Text {
+            x: 15 * pt
+            height: parent.height
+            verticalAlignment: Text.AlignVCenter
+            font: quicksandFonts.medium11
+            text: qsTr("Optional")
+            color: "white"
+        }
+
+    }   //optionalTitle
+
+
+    Item {
+        id: optionalBody
+        y: optionalTitle.y + optionalTitle.height
+        width: parent.width
+        height: parent.height - y
+
+        ColumnLayout {
+            id: optionalBodyLayout
+            spacing: 24 * pt
+            y: spacing
+            x: 15 * pt
+            width: parent.width - x
+
+            Repeater {
+                id: optionalRepeater
+
+                InputField {
+                    Layout.preferredHeight: 28 * pt
+                    Layout.preferredWidth: 277 * pt
+                    leftPadding: 0
+                    smartPlaceHolderText: model.placeHolderText
+                    color: focus ? "#D51F5D" : "#070023"
+                    inputMask: model.inputFieldMask
+
+                    font: quicksandFonts.regular16
+                    onEditingFinished: {
+                        text = text.trim()
+                        optionalRepeater.model.setProperty(model.index, "data", text)
+                    }
+                }
+
+            }  //
+
+
+            DapButton {
+                id: createButton
+                textButton: qsTr("Create")
+                Layout.preferredWidth: 132 * pt
+                Layout.preferredHeight: 36 * pt
+                Layout.alignment: Qt.AlignHCenter
+
+                enabled: root.requiredFieldValid
+                colorBackgroundNormal: enabled ? "#271C4E" : "white"
+                colorBackgroundHover: enabled ? "#D2145D" : "white"
+                colorButtonTextNormal: enabled ? "#FFFFFF" : "#211A3A"
+                colorButtonTextHover: enabled ? "#FFFFFF" : "#211A3A"
+                borderColorButton: enabled ? "#000000" : "#211A3A"
+                borderWidthButton: enabled ? 0 : (1 * pt)
+                radius: 4 * pt
+                fontButton: quicksandFonts.regular16
+                horizontalAligmentText: Qt.AlignHCenter
+            }
+
+
+        }  //optionalBodyeLayout
+
+
+    }  //optionalBody
+
+
+
+
+
+
+}   //root
+
+
+
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CreateFinishedItem.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CreateFinishedItem.qml
new file mode 100644
index 0000000..d50d765
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CreateFinishedItem.qml
@@ -0,0 +1,92 @@
+import QtQuick 2.9
+import "qrc:/widgets"
+import "parts"
+
+
+
+
+Rectangle {
+    id: root
+    property alias closeButton: closeButton
+    property alias doneButton: doneButton
+    property alias finishedText: finishedText
+
+    implicitWidth: 100
+    implicitHeight: 200
+
+    border.color: "#E2E1E6"
+    border.width: 1 * pt
+    radius: 8 * pt
+    color: "transparent"
+
+    //part animation on created and open
+    visible: false
+    opacity: visible ? 1.0 : 0.0
+    Behavior on opacity {
+        NumberAnimation {
+            duration: 100
+            easing.type: Easing.InOutQuad
+        }
+    }
+
+
+    Item {
+        id: titleRectangle
+        width: parent.width
+        height: 40 * pt
+
+        CloseButton {
+            id: closeButton
+        }  //
+
+
+        Text {
+            id: certificatesTitleText
+            anchors{
+                left: closeButton.right
+                leftMargin: 18 * pt
+                verticalCenter: closeButton.verticalCenter
+            }
+            font: quicksandFonts.bold14
+            color: "#3E3853"
+            text: qsTr("Create certificate")
+        }
+    }  //titleRectangle
+
+
+    Text {
+        id: finishedText
+        y: 202 * pt
+        anchors.horizontalCenter: parent.horizontalCenter
+        font: quicksandFonts.medium27
+        color: "#070023"
+        text: qsTr("Certificate created\nsuccessfully")
+        horizontalAlignment: Text.AlignHCenter
+    }
+
+
+    DapButton {
+        id: doneButton
+        textButton: qsTr("Done")
+        y: 468 * pt
+        x: (parent.width - width) / 2
+        height: 36 * pt
+        width: 132 * pt
+        colorBackgroundNormal: "#271C4E"
+        colorBackgroundHover: "#D2145D"
+        colorButtonTextNormal: "#FFFFFF"
+        colorButtonTextHover: "#FFFFFF"
+        borderColorButton: "#000000"
+        borderWidthButton: 0
+        radius: 4 * pt
+        fontButton: quicksandFonts.regular16
+        horizontalAligmentText: Qt.AlignHCenter
+    }
+
+
+
+
+}   //root
+
+
+
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/DapCertificatesMainPage.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/DapCertificatesMainPage.qml
new file mode 100644
index 0000000..eeda098
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/DapCertificatesMainPage.qml
@@ -0,0 +1,320 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+import DapCertificateManager.Commands 1.0
+import "qrc:/widgets"
+import "parts"
+
+
+Rectangle
+{
+    id: dapCertificatesMainPage
+
+
+    Utils {
+        id: utils
+    }
+
+
+
+
+    CertificatesModels {
+        id: models
+    }
+
+    CertificatesLogic{
+        id: logics
+    }
+
+
+    HeaderItem {
+        id: headerItem
+        x: 3 * pt
+        width: parent.width
+        height: 60 * pt
+
+        onFindHandler: {    //text
+            models.certificatesFind.findString = text
+            models.certificatesFind.update()
+        }
+    }
+
+
+
+    CertificatesListView {
+        id: certificatesListView
+        x: 24 * pt
+        y: 84 * pt
+        height: parent.height - y - 24 * pt
+        width: 678 * pt
+        infoTitleTextVisible: models.certificates.isSelected
+
+
+        Component.onCompleted: {
+            //need bind delegate with delegateModel
+            models.certificatesFind.delegate = delegateComponent
+            models.certificatesFind.accessKeyTypeIndex = DapCertificateType.Public           //default open access type is public
+            models.certificatesFind.update()
+            model = models.certificatesFind  //original
+//            delegate = delegateComponent
+//            model = models.certificates
+        }
+
+        onSelectedIndex: {   //index
+//            if (models.certificates.selectedIndex === index)       //clear selected with repeat click
+//                models.certificates.clearSelected()
+//            else
+              models.certificates.setSelectedIndex(index)
+        }
+
+        onInfoClicked: {     //index
+            logics.dumpCertificate(index)
+            rightPanel.sourceComponent = certificateInfoComponent
+        }
+
+    }   //certificatesListView
+
+
+    Loader {
+        id: rightPanel
+        anchors {
+            right: parent.right
+            rightMargin: 26 * pt
+        }
+        asynchronous: true
+        y: certificatesListView.y
+        width: 348 * pt
+        height: certificatesListView.height
+        sourceComponent: certificatesActionsComponent
+
+        onLoaded: {
+            item.visible = true
+        }
+
+    }  //rightPanel
+
+
+
+    Component {
+        id: certificatesActionsComponent
+
+        CertificatesActionsButtonList {
+            certificateSelected: models.certificates.isSelected
+            bothAccessTypeCertificateSelected: models.accessKeyType.bothTypeCertificateSelected
+            certificateAccessTypeRepeater.model: models.accessKeyType
+
+
+            onSelectedAccessKeyType: {               //index
+                models.accessKeyType.setSelectedIndex(index)
+                models.certificates.clearSelected()
+                switch (index) {
+                    case 0:      //"public"
+                        certificatesListView.seletedCertificateAccessType = qsTr("Public")
+                        models.certificatesFind.accessKeyTypeIndex = DapCertificateType.Public
+                        models.certificatesFind.update()
+                        break;
+                    case 1:      //"private"
+                        certificatesListView.seletedCertificateAccessType = qsTr("Private")
+                        models.certificatesFind.accessKeyTypeIndex = DapCertificateType.Private
+                        models.certificatesFind.update()
+                        break;
+                    case 2:      //"both"
+                        certificatesListView.seletedCertificateAccessType = qsTr("Both")
+                        models.certificatesFind.accessKeyTypeIndex = DapCertificateType.Both
+                        models.certificatesFind.update()
+                        break;
+                    default:
+                        console.error("Unknown index", index)
+                        break;
+                }
+            }
+
+
+            createCertificateButton.onClicked: {
+                rightPanel.sourceComponent = createCertificateComponent
+            }
+
+            exportPublicCertificateToFileButton.onClicked: {
+                logics.exportPublicCertificateToFile(models.certificates.selectedIndex)
+            }
+
+            exportPublicCertificateToMempoolButton.onClicked: {
+                logics.exportPublicCertificateToMempool(models.certificates.selectedIndex)
+            }
+
+            deleteCertificateButton.onClicked: {
+                 logics.deleteCertificate(models.certificates.selectedIndex)
+            }
+
+            //TODO
+//            importCertificateButton
+//            addSignatureToCertificateButton
+
+        }  //
+    }  //certificatesActionsComponent
+
+
+    Component {
+        id: createCertificateComponent
+        CreateCertificateItem {
+            optionalModel: models.createCertificateOptional
+            signatureTypeCertificateComboBox.model: models.signatureType
+            requiredFieldValid: false //TODO
+
+            function checkRequiredField(){
+                requiredFieldValid = titleCertificateTextInput.text.length > 0
+                                     && signatureTypeCertificateComboBox.currentIndex >= 0
+            }
+
+            function checkOptionalField(){
+                for (var i = 0; i < models.createCertificateOptional.count; ++i) {
+                    var optionalField = models.createCertificateOptional.get(i)
+                    var data = optionalField.data
+                    switch (optionalField.key) {
+                        case "domain":
+                            if (data !== "" && !utils.validDomain(optionalField.data)) {
+                                messagePopup.smartOpen(qsTr("%1 not correct").arg(optionalField.placeHolderText)
+                                                       , "Please fill field correctly.")
+                                return false;
+                            }
+                            break;
+                        case "expiration_date":
+                            if (data !== "" && !utils.validDate(optionalField.data)) {
+                                messagePopup.smartOpen(qsTr("%1 not correct").arg(optionalField.placeHolderText)
+                                                       , "Please fill field correctly.")
+                                return false;
+                            }
+                            break;
+                        case "email":
+                            if (data !== "" && !utils.validEmail(optionalField.data)) {
+                                messagePopup.smartOpen(qsTr("%1 not correct").arg(optionalField.placeHolderText)
+                                                       , "Please fill field correctly.")
+                                return false;
+                            }
+                            break;
+                    }
+                }
+
+                return true;
+            }
+
+            signatureTypeCertificateComboBox.onCurrentIndexChanged: {
+                checkRequiredField()
+            }
+
+            closeButton.onClicked: {
+                rightPanel.sourceComponent = certificatesActionsComponent
+            }
+
+            createButton.onClicked: {   //enabled when requiredFieldValid
+                if (checkOptionalField())
+                    logics.createCertificate(titleCertificateTextInput.text
+                                             , models.signatureType.get(signatureTypeCertificateComboBox.currentIndex).signature
+                                             , models.createCertificateOptional.getDataToJson())
+                else
+                    console.warn("not valid optional field")
+            }
+
+            titleCertificateTextInput.onEditingFinished: {
+                checkRequiredField()
+            }
+
+            titleCertificateTextInput.onTextChanged: {
+                checkRequiredField()
+            }
+
+
+        }
+    }  //createCertificateComponent
+
+    Component {
+        id: createFinishedItemComponent
+        CreateFinishedItem {
+            doneButton.onClicked: {
+                rightPanel.sourceComponent = certificatesActionsComponent
+            }
+        }
+    }
+
+    Component {
+        id: certificateInfoComponent
+        CertificateInfoItem {
+            certificateDataListView.model: models.certificateInfo
+            closeButton.onClicked: {
+                rightPanel.sourceComponent = certificatesActionsComponent
+            }
+        }
+    }
+
+
+    Popup{
+        id: messagePopup
+        closePolicy: "NoAutoClose"
+        padding: 0
+        background: Item { }
+        width: dapMessageBox.width
+        height: dapMessageBox.height
+        x: (parent.width - width) / 2
+        y: (parent.height - height) / 2
+        modal: true
+
+        function smartOpen(title, contentText) {
+            dapMessageBox.dapTitleText.text = title
+            dapMessageBox.dapContentText.text = contentText
+            open()
+        }
+
+        DapMessageBox {
+            id: dapMessageBox
+            width: 240 * pt
+            height: 240 * pt
+            dapButtonOk.onClicked: {
+                messagePopup.close()
+            }
+        }
+    }
+
+
+
+
+
+    Loader {
+        id: blockBusyIndicatorLoader
+        active: logics.requestRunning
+        width: parent.width
+        height: parent.height
+        sourceComponent: Component {
+            Popup{
+                id: messagePopup
+                closePolicy: "NoAutoClose"
+                padding: 0
+                background: Rectangle{
+                    width: parent.width
+                    height: parent.height
+                    radius: 12 * pt
+                }
+                width: dapMessageBox.width
+                height: dapMessageBox.height
+                x: (blockBusyIndicatorLoader.width - width) / 2
+                y: (blockBusyIndicatorLoader.height - height) / 2
+                modal: true
+
+                BusyIndicator {
+                    anchors.centerIn: parent
+                    width: 120 * pt
+                    height: 120 * pt
+                    running: true
+                }
+            }
+        }
+
+        onLoaded: {
+            item.parent = dapCertificatesMainPage
+            item.open()
+        }
+    }   //
+
+
+
+
+
+}   //dapCertificatesMainPage
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/HeaderItem.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/HeaderItem.qml
new file mode 100644
index 0000000..c526750
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/HeaderItem.qml
@@ -0,0 +1,58 @@
+import QtQuick 2.4
+import QtQuick.Controls 2.0
+import "qrc:/widgets"
+import "parts"
+
+
+
+Rectangle {
+    id: root
+
+    signal findHandler(string text)
+
+    //color: "#211A3A"    //design color
+    color: "#070023"      //original color
+    radius: 8 * pt
+
+
+    implicitWidth: searchBox.x + searchBox.width
+    implicitHeight: searchBox.y + searchBox.height
+
+
+
+    SearchInputBox {
+        id: searchBox
+        x: 38 * pt
+        anchors.verticalCenter: parent.verticalCenter
+
+        placeholderText: qsTr("Search")
+        height: 28 * pt
+        width: Math.max(Math.min(leftPadding + contentWidth, root.width - searchBox.x * 2), 228 * pt)
+        color: "#B0AEB9"
+        font: quicksandFonts.regular14
+
+        onEditingFinished: {
+            filtering.clear()
+            root.findHandler(text)
+        }
+
+        filtering.waitInputInterval: 100
+        filtering.minimumSymbol: 0
+        filtering.onAwaitingFinished: {
+            root.findHandler(text)
+        }
+
+    }
+
+
+    //right Rectangle
+    Rectangle {
+        color: parent.color
+        height: parent.height
+        width: parent.radius
+        x: parent.width - width
+    }
+
+
+}  //root
+
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/models/FindDelegateModel.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/models/FindDelegateModel.qml
new file mode 100644
index 0000000..38c2dfb
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/models/FindDelegateModel.qml
@@ -0,0 +1,73 @@
+import QtQuick 2.9
+import QtQml.Models 2.3
+
+
+/*
+
+  need move to common module
+
+
+*/
+
+
+
+DelegateModel {
+    id: root
+    items.includeByDefault: false
+
+
+    property var predicate: function(obj) { return true; }
+
+
+    function clear() {       //move from visible and pending group to unusable group
+        console.log("FindDelegateModel.clear()", items.count, pendingItems.count)
+        if (items.count > 0)
+            items.setGroups(0, items.count, "unusable")
+        if (pendingItems.count > 0)
+            pendingItems.setGroups(0, pendingItems.count, "unusable")
+    }
+
+
+    function renew() {        //find in base model
+//        console.log("FindDelegateModel.renew(), items.count: %1, unusableItems.count: %2, pendingItems.count: %3"
+//                    .arg(items.count).arg(unusableItems.count).arg(pendingItems.count))
+
+        if (items.count > 0)
+            items.setGroups(0, items.count, "pending")
+        if (unusableItems.count > 0)
+            unusableItems.setGroups(0, unusableItems.count, "pending")
+    }
+
+
+    groups: [
+        DelegateModelGroup {           //item wait for find
+            id: pendingItems
+            name: "pending"
+
+            includeByDefault: true
+            onChanged: {
+                while (pendingItems.count > 0) {
+                    var item = pendingItems.get(0)
+
+                    if (predicate(item.model))
+                        item.groups = "items"
+                    else
+                        item.groups = "unusable"
+                }
+            }
+        },   //pending group end
+        DelegateModelGroup {           //item no equal by find predicate
+            id: unusableItems
+            name: "unusable"
+            includeByDefault: false
+
+//            onChanged: {
+//                console.log("unusableItems.onChanged:, unusableItems.count:", unusableItems.count)
+//            }
+        }
+    ]
+
+
+
+}  //root
+
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/CloseButton.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/CloseButton.qml
new file mode 100644
index 0000000..06d86ce
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/CloseButton.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+
+
+//fixed define button fo module certificate
+
+
+ToolButton {
+    id: root
+    x: 14 * pt
+    y: 6 * pt
+    height: 28 * pt
+    width: height
+
+    image.anchors {
+        right: root.right
+        rightMargin: 14 * pt
+    }
+    image.source: isHovered ? "qrc:/resources/icons/Certificates/close_icon_hover.svg"
+                            : "qrc:/resources/icons/Certificates/close_icon.svg"
+    image.width: 20 * pt
+    image.height: 20 * pt
+}  //
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/CreateCertificateModel.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/CreateCertificateModel.qml
new file mode 100644
index 0000000..dcdcf70
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/CreateCertificateModel.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+
+
+
+//этот компонент должен лежать в подкаталоге models
+
+
+
+Item {
+
+
+
+
+
+}
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/FindDelegateModel.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/FindDelegateModel.qml
new file mode 100644
index 0000000..4d98810
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/FindDelegateModel.qml
@@ -0,0 +1,73 @@
+import QtQuick 2.9
+import QtQml.Models 2.3
+
+
+/*
+
+  need move to common module
+
+
+*/
+
+
+
+DelegateModel {
+    id: root
+    items.includeByDefault: false
+
+
+    property var predicate: function(obj) { return true; }
+
+
+    function clear() {       //move from visible and pending group to unusable group
+        console.log("FindDelegateModel.clear()", items.count, pendingItems.count)
+        if (items.count > 0)
+            items.setGroups(0, items.count, "unusable")
+        if (pendingItems.count > 0)
+            pendingItems.setGroups(0, pendingItems.count, "unusable")
+    }
+
+
+    function renew() {        //find in base model
+        console.log("FindDelegateModel.renew(), items.count: %1, unusableItems.count: %2, pendingItems.count: %3"
+                    .arg(items.count).arg(unusableItems.count).arg(pendingItems.count))
+
+        if (items.count > 0)
+            items.setGroups(0, items.count, "pending")
+        if (unusableItems.count > 0)
+            unusableItems.setGroups(0, unusableItems.count, "pending")
+    }
+
+
+    groups: [
+        DelegateModelGroup {           //item wait for find
+            id: pendingItems
+            name: "pending"
+
+            includeByDefault: true
+            onChanged: {
+                while (pendingItems.count > 0) {
+                    var item = pendingItems.get(0)
+
+                    if (predicate(item.model))
+                        item.groups = "items"
+                    else
+                        item.groups = "unusable"
+                }
+            }
+        },   //pending group end
+        DelegateModelGroup {           //item no equal by find predicate
+            id: unusableItems
+            name: "unusable"
+            includeByDefault: false
+
+//            onChanged: {
+//                console.log("unusableItems.onChanged:, unusableItems.count:", unusableItems.count)
+//            }
+        }
+    ]
+
+
+
+}  //root
+
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/InputField.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/InputField.qml
new file mode 100644
index 0000000..15d7633
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/InputField.qml
@@ -0,0 +1,78 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+import QtQuick.Layouts 1.3
+
+
+//NOTE not use inner placeholderText:
+//part common module
+
+
+TextField {
+    id: root
+
+    property alias borderLine: borderLine
+    property alias borderRadius: borderLine.radius
+    property alias placeholderTextView: placeholderTextView
+
+    property string smartPlaceHolderText: ""
+    //placeholderTextColor: color     //5.12
+    property string placeholderTextColor: "#C7C6CE"    //5.10
+
+    property int borderWidth: 1 * pt
+    property int borderWidthWhenFocus: 2 * pt
+
+    property color backgroundColor: "transparent"
+    property color backgroundColorWhenDisabled: backgroundColor
+    property color borderColor: "#C7C6CE"
+    property color borderColorWhenDisabled: borderColor
+
+
+    color: "#070023"
+    verticalAlignment: TextInput.AlignVCenter
+    selectByMouse: false
+    //inputMethodHints: Qt.ImhPreferLowercase
+
+    leftPadding: 12 * pt
+    rightPadding: 6 * pt
+    topPadding: 3 * pt
+    bottomPadding: 6 * pt
+
+
+    Text {
+        id: placeholderTextView
+        visible: root.displayText === ""
+        color: root.placeholderTextColor
+        text: root.smartPlaceHolderText
+        anchors.fill: parent
+
+        verticalAlignment: root.verticalAlignment
+        horizontalAlignment: root.horizontalAlignment
+        elide: Text.ElideRight
+
+        leftPadding: root.leftPadding
+        rightPadding: root.rightPadding
+        topPadding: root.topPadding
+        bottomPadding: root.bottomPadding
+
+        font: root.font
+    }
+
+
+    Rectangle {
+        id: borderLine
+        z: -1
+        anchors.bottom: parent.bottom
+        width: parent.width
+        height: 1 * pt
+        color: root.enabled ? backgroundColor : backgroundColorWhenDisabled
+        border.color: root.enabled ? borderColor : borderColorWhenDisabled
+        border.width: root.activeFocus ? borderWidthWhenFocus : borderWidth
+    }
+
+
+    //empty default background
+    background: Item {  }
+
+
+
+}   //root
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/PlaceholderTextView.qml.autosave b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/PlaceholderTextView.qml.autosave
new file mode 100644
index 0000000..75ef5b3
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/PlaceholderTextView.qml.autosave
@@ -0,0 +1,13 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+import QtQuick.Layouts 1.3
+
+
+
+Item {
+
+    
+    
+    
+    
+}
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/SearchInputBox.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/SearchInputBox.qml
new file mode 100644
index 0000000..cb2e2c1
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/SearchInputBox.qml
@@ -0,0 +1,103 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
+
+
+/*
+
+  need move to common module
+
+
+*/
+
+
+
+TextField {
+    id: root
+
+    property alias filtering: filtering
+    property alias searchImage: searchImage
+    property int spacing: 10 * pt
+
+
+    implicitHeight: 50 * pt
+    implicitWidth: 100 * pt
+    leftPadding: searchImage.width + spacing
+    font.pixelSize: 14 * pt
+    topPadding: 0
+    bottomPadding: 8 * pt
+
+
+    Image{
+        id: searchImage
+        width: 20 * pt
+        height: 20 * pt
+        fillMode: Image.PreserveAspectFit
+        verticalAlignment: Image.AlignVCenter
+        horizontalAlignment: Image.AlignHCenter
+
+        source: "qrc:/resources/icons/ic_search.png"
+    }
+
+    background: Item {  }
+
+
+    //bottom line
+    Rectangle {
+        width: parent.width
+        height: 1 * pt
+        y: parent.height
+        color: "#453F5A"
+
+        Behavior on width {
+            NumberAnimation {
+                duration: 100
+                easing.type: Easing.InOutQuad
+            }
+        }
+    }
+
+
+    onTextChanged: {
+        filtering.filter(text)
+    }
+
+    //for mobile input
+    onDisplayTextChanged: {
+        filtering.filter(text)
+    }
+
+
+    //optional
+//            onAccepted: {
+//                console.log("SearchInputBox.onAccepted:", text)
+//            }
+
+//            onEditingFinished: {
+//                filtering.clear()
+//                console.log("SearchInputBox.onEditingFinished:", text)
+//            }
+
+
+//            onTextEdited: {
+//                console.log("SearchInputBox.onEdited:", text)
+//            }
+
+
+    TextInputFilter {
+        id: filtering
+        minimumSymbol: 3
+        waitInputInterval: 500
+        onAwaitingFinished: {
+            //console.log("onAwaitingFinished:", text)
+        }
+    }
+
+
+
+
+} // root
+
+
+
+
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/TextInputFilter.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/TextInputFilter.qml
new file mode 100644
index 0000000..4a45342
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/TextInputFilter.qml
@@ -0,0 +1,70 @@
+import QtQuick 2.0
+
+
+
+Item {
+    id: root
+
+    signal awaitingFinished(string text)
+
+    property alias blockInputInterval: blockInputTimer.interval
+    property alias waitInputInterval: waitInputTimer.interval
+
+    readonly property alias validTextLength: pObj.validTextLength
+    readonly property alias awaitingValidText: pObj.awaitingValidText
+
+    property int minimumSymbol: 3
+
+
+    //for set text in text field without  signal emited
+    function blockSignal(){
+        blockInputTimer.restart()
+    }
+
+
+    //use this function for filtering text after changed in input field
+    function filter(text){
+        pObj.validTextLength = text.length >= minimumSymbol
+        //console.log("TextInputFiltering.filter:", text, validTextLength)
+
+        if (!blockInputTimer.running){
+            if (validTextLength) {            //минимум символов для поиска адресов 3
+                pObj.awaitingValidText = text
+                waitInputTimer.restart()
+            }
+        }
+
+    }
+
+
+    function clear(){
+        blockInputTimer.stop()
+        waitInputTimer.stop()
+        pObj.awaitingValidText = ""
+    }
+
+
+    Timer{
+        id: blockInputTimer
+        interval: 600
+    }
+
+    Timer{
+        id: waitInputTimer
+        interval: 1000
+        onTriggered: {
+           awaitingFinished(pObj.awaitingValidText)  //возможно неверный объект
+        }
+    }
+
+
+    QtObject{
+        id: pObj
+        property bool validTextLength: false
+        property string awaitingValidText: ""
+    }
+
+
+}   //root
+
+
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/TitleTextView.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/TitleTextView.qml
new file mode 100644
index 0000000..d1075f3
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/TitleTextView.qml
@@ -0,0 +1,39 @@
+import QtQuick 2.9
+import QtQuick.Layouts 1.3
+
+
+
+Item {
+    id: root
+
+    property alias title: title
+    property alias content: content
+
+    property int verticalSpacing: 10 * pt
+
+
+    implicitWidth: Math.max(title.width, content.width)
+    implicitHeight: title.height + verticalSpacing + content.height
+
+
+    Text {
+        id: title
+        font: quicksandFonts.regular12
+        color: "#B4B1BD"
+        elide: Text.ElideRight
+        maximumLineCount: 1
+    }
+
+
+
+    Text {
+        id: content
+        y: title.height + verticalSpacing
+        font: quicksandFonts.regular14
+        color: "#070023"
+        elide: Text.ElideRight
+        maximumLineCount: 1
+    }
+
+
+}   //
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/ToolButton.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/ToolButton.qml
new file mode 100644
index 0000000..e5ee924
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/ToolButton.qml
@@ -0,0 +1,39 @@
+import QtQuick 2.9
+
+
+/*
+
+  need move to common module
+
+*/
+
+
+MouseArea {
+    property alias image: image
+    property bool isHovered: false
+
+    implicitHeight: 50
+    implicitWidth: 50
+    hoverEnabled: true
+
+    onEntered: {
+        isHovered = true
+    }
+
+    onExited: {
+        isHovered = false
+    }
+
+    Image {
+        id: image
+        x: (parent.width - width) / 2
+        y: (parent.height - height) / 2
+        width: parent.width / 2
+        height: parent.height / 2
+        verticalAlignment: Image.AlignVCenter
+        horizontalAlignment: Image.AlignHCenter
+    }
+
+
+
+}   //
diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/Utils.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/Utils.qml
new file mode 100644
index 0000000..d3af1ba
--- /dev/null
+++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/Utils.qml
@@ -0,0 +1,72 @@
+import QtQuick 2.0
+
+Item {
+    id: root
+
+//        Component.onCompleted: {           //for test
+//            console.log("valid test"
+//                        , utils.validDate("05.05.2020")
+//                        , utils.validDomain("mkyong-info.com")
+//                        , utils.validEmail("mkyong...@info.com")
+//                        , utils.validDate("05.55.2020")
+//                        , utils.validDomain("mkyong?info.com")
+//                        , utils.validEmail("mkyong//@info.com")    )
+
+//            console.info(replaceChars("11.11.2222", '.', '-'))
+//        }
+
+
+    //litle beatifuler visual json,
+    function beatifulerJSON(json, message){
+        console.log( (typeof message != 'undefined' ? message + ', ' : "")
+                    , ':',  JSON.stringify(json, null, '    ') )               //невыводит на больших массивах данных
+    }
+
+    function beatifulerJSONKeys(json, message){
+        console.log( (typeof message != 'undefined' ? message + ', ' : "")
+                    , 'Keys:',  JSON.stringify(Object.keys(json)
+                    , null, '    ') )
+    }
+
+
+    function validEmail(email){
+        var regExp = /^[\w\.\d-_+]+@[\w\.\d-_+]+\.\w{2,4}$/i;      //maybe $ in the end
+        return regExp.test(email)
+    }
+
+
+    function validDomain(domain){
+        console.log("domain", domain)
+        var regExp = /^(?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63}$/;
+        return regExp.test(domain)
+    }
+
+
+    function validDate(date){
+        var regExp = /^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/m;
+        return regExp.test(date)
+    }
+
+
+    function replaceChars(text, findChar, replaceChar){
+        return text.split(findChar).join(replaceChar)
+    }
+
+
+
+}   //root
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CellFrameDashboardGUI/screen/desktop/Dashboard/RightPanel/DapInputNewWalletNameRightPanel.qml b/CellFrameDashboardGUI/screen/desktop/Dashboard/RightPanel/DapInputNewWalletNameRightPanel.qml
index b9df394..2cd0de6 100644
--- a/CellFrameDashboardGUI/screen/desktop/Dashboard/RightPanel/DapInputNewWalletNameRightPanel.qml
+++ b/CellFrameDashboardGUI/screen/desktop/Dashboard/RightPanel/DapInputNewWalletNameRightPanel.qml
@@ -14,7 +14,9 @@ DapInputNewWalletNameRightPanelForm
         console.log(dapTextInputNameWallet.text)
         console.log(dapSignatureTypeWallet)
         console.log(dapServiceController.CurrentNetwork)
-        dapServiceController.requestToService("DapAddWalletCommand", dapTextInputNameWallet.text, dapSignatureTypeWallet, dapServiceController.CurrentNetwork, "0xad12dec5ab4f");
+        dapServiceController.requestToService("DapAddWalletCommand", dapTextInputNameWallet.text    //original
+                                              , dapSignatureTypeWallet, dapServiceController.CurrentNetwork
+                                              , "0xad12dec5ab4f");
     }
 
     dapButtonClose.onClicked:
diff --git a/CellFrameDashboardService/CellFrameDashboardService.pro b/CellFrameDashboardService/CellFrameDashboardService.pro
index 25bb811..7b512ed 100755
--- a/CellFrameDashboardService/CellFrameDashboardService.pro
+++ b/CellFrameDashboardService/CellFrameDashboardService.pro
@@ -3,6 +3,12 @@ QT += core network gui widgets
 CONFIG += c++11 console
 CONFIG -= app_bundle
 
+
+LIBS += -ldl
+#LIBS+=-lz #-lz -lrt -lm -lpthread   -lrt -lm -lpthread
+#+LIBS+=-lrt
+
+
 !defined(BRAND,var){
 #  Default brand
     BRAND = CellFrameDashboard
@@ -19,11 +25,13 @@ win32 {
     CONFIG -= console
     VERSION = $${VER_MAJ}.$${VER_MIN}.$$VER_PAT
     DEFINES += CLI_PATH=\\\"cellframe-node-cli.exe\\\"
+    DEFINES += TOOLS_PATH=\\\"cellframe-node-tool.exe\\\"
     DEFINES += HAVE_STRNDUP
 }
 else {
     VERSION = $$VER_MAJ\.$$VER_MIN\-$$VER_PAT
     DEFINES += CLI_PATH=\\\"/opt/cellframe-node/bin/cellframe-node-cli\\\"
+    DEFINES += TOOLS_PATH=\\\"/opt/cellframe-node/bin/cellframe-node-tool\\\"
     DEFINES += LOG_FILE=\\\"/opt/cellframe-node/var/log/cellframe-node.log\\\"
     DEFINES += CMD_HISTORY=\\\"/opt/cellframe-dashboard/data/cmd_history.txt\\\"
 }
diff --git a/CellFrameDashboardService/DapServiceController.cpp b/CellFrameDashboardService/DapServiceController.cpp
index f4acca1..f376795 100755
--- a/CellFrameDashboardService/DapServiceController.cpp
+++ b/CellFrameDashboardService/DapServiceController.cpp
@@ -49,6 +49,9 @@ bool DapServiceController::start()
 /// Register command.
 void DapServiceController::registerCommand()
 {
+    //all certificates commands for module certificate in
+    m_pServer->addService(new DapCertificateManagerCommands("DapCertificateManagerCommands", m_pServer, CLI_PATH, TOOLS_PATH));
+
     // Application shutdown team
     m_pServer->addService(new DapQuitApplicationCommand("DapQuitApplicationCommand", m_pServer));
     // GUI client activation command in case it is minimized/expanded
diff --git a/CellFrameDashboardService/DapServiceController.h b/CellFrameDashboardService/DapServiceController.h
index a9c7ed0..792893c 100755
--- a/CellFrameDashboardService/DapServiceController.h
+++ b/CellFrameDashboardService/DapServiceController.h
@@ -39,6 +39,8 @@ typedef class DapRpcLocalServer DapUiService;
 #include "handlers/DapRunCmdCommand.h"
 #include "handlers/DapGetHistoryExecutedCmdCommand.h"
 #include "handlers/DapSaveHistoryExecutedCmdCommand.h"
+#include "handlers/DapCertificateManagerCommands.h"
+
 #include "DapSystemTrayIcon.h"
 #include "DapToolTipWidget.h"
 
-- 
GitLab