summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--framework/src/CMakeLists.txt1
-rw-r--r--framework/src/domain/maillistmodel.cpp9
-rw-r--r--framework/src/frameworkplugin.cpp2
-rw-r--r--framework/src/logmodel.cpp76
-rw-r--r--framework/src/logmodel.h41
-rw-r--r--views/log/main.qml12
-rw-r--r--views/log/qml/View.qml45
-rw-r--r--views/log/tests/tst_logview.qml30
8 files changed, 164 insertions, 52 deletions
diff --git a/framework/src/CMakeLists.txt b/framework/src/CMakeLists.txt
index 5ad5e910..901ec4a3 100644
--- a/framework/src/CMakeLists.txt
+++ b/framework/src/CMakeLists.txt
@@ -54,6 +54,7 @@ add_library(kubeframework SHARED
54 extensionmodel.cpp 54 extensionmodel.cpp
55 viewhighlighter.cpp 55 viewhighlighter.cpp
56 file.cpp 56 file.cpp
57 logmodel.cpp
57 ) 58 )
58generate_export_header(kubeframework BASE_NAME Kube EXPORT_FILE_NAME kube_export.h) 59generate_export_header(kubeframework BASE_NAME Kube EXPORT_FILE_NAME kube_export.h)
59set_target_properties(kubeframework PROPERTIES 60set_target_properties(kubeframework PROPERTIES
diff --git a/framework/src/domain/maillistmodel.cpp b/framework/src/domain/maillistmodel.cpp
index 5936c792..152b4f23 100644
--- a/framework/src/domain/maillistmodel.cpp
+++ b/framework/src/domain/maillistmodel.cpp
@@ -406,6 +406,15 @@ bool MailListModel::showInbox() const
406void MailListModel::setEntityId(const QString &id) 406void MailListModel::setEntityId(const QString &id)
407{ 407{
408 qDebug() << "Running mail query for mail with ID:" << id; 408 qDebug() << "Running mail query for mail with ID:" << id;
409 if (id.isEmpty()) {
410 mCurrentQueryItem.clear();
411 setSourceModel(nullptr);
412 return;
413 }
414 if (mCurrentQueryItem == id) {
415 return;
416 }
417 mCurrentQueryItem = id.toLatin1();
409 using namespace Sink::ApplicationDomain; 418 using namespace Sink::ApplicationDomain;
410 Sink::Query query; 419 Sink::Query query;
411 query.setFlags(Sink::Query::LiveQuery); 420 query.setFlags(Sink::Query::LiveQuery);
diff --git a/framework/src/frameworkplugin.cpp b/framework/src/frameworkplugin.cpp
index b5635733..9c81b7e1 100644
--- a/framework/src/frameworkplugin.cpp
+++ b/framework/src/frameworkplugin.cpp
@@ -46,6 +46,7 @@
46#include "extensionmodel.h" 46#include "extensionmodel.h"
47#include "viewhighlighter.h" 47#include "viewhighlighter.h"
48#include "file.h" 48#include "file.h"
49#include "logmodel.h"
49 50
50#include <QtQml> 51#include <QtQml>
51#include <QQuickImageProvider> 52#include <QQuickImageProvider>
@@ -178,6 +179,7 @@ void FrameworkPlugin::registerTypes (const char *uri)
178 qmlRegisterType<ContactController>(uri, 1, 0,"ContactController"); 179 qmlRegisterType<ContactController>(uri, 1, 0,"ContactController");
179 qmlRegisterType<PeopleModel>(uri, 1, 0,"PeopleModel"); 180 qmlRegisterType<PeopleModel>(uri, 1, 0,"PeopleModel");
180 qmlRegisterType<TextDocumentHandler>(uri, 1, 0, "TextDocumentHandler"); 181 qmlRegisterType<TextDocumentHandler>(uri, 1, 0, "TextDocumentHandler");
182 qmlRegisterType<LogModel>(uri, 1, 0, "LogModel");
181 183
182 qmlRegisterType<AccountFactory>(uri, 1, 0, "AccountFactory"); 184 qmlRegisterType<AccountFactory>(uri, 1, 0, "AccountFactory");
183 qmlRegisterType<AccountsModel>(uri, 1, 0, "AccountsModel"); 185 qmlRegisterType<AccountsModel>(uri, 1, 0, "AccountsModel");
diff --git a/framework/src/logmodel.cpp b/framework/src/logmodel.cpp
new file mode 100644
index 00000000..c3a692dc
--- /dev/null
+++ b/framework/src/logmodel.cpp
@@ -0,0 +1,76 @@
1/*
2 Copyright (c) 2018 Christian Mollekopf <mollekopf@kolabsys.com>
3
4 This library is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19
20#include "logmodel.h"
21
22#include <QDebug>
23#include <QDateTime>
24#include <QStandardItem>
25
26LogModel::LogModel(QObject *parent)
27 : QStandardItemModel(parent)
28{
29 QByteArrayList roles{"type", "subtype", "timestamp", "message", "details", "entities", "resource"};
30
31 int role = Qt::UserRole + 1;
32 mRoles.insert("id", role);
33 role++;
34 for (const auto &r : roles) {
35 mRoles.insert(r, role);
36 role++;
37 }
38
39 QHash<int, QByteArray> roleNames;
40 for (const auto r : mRoles.keys()) {
41 roleNames.insert(mRoles[r], r);
42 }
43 setItemRoleNames(roleNames);
44}
45
46LogModel::~LogModel()
47{
48
49}
50
51void LogModel::insert(const QVariantMap &message)
52{
53
54 if (rowCount() > 0) {
55 auto i = item(0);
56 const auto subtype = i->data(mRoles["subtype"]).toString();
57 if (!subtype.isEmpty() && (subtype == message.value("subtype").toString())) {
58 //TODO merge message into this entry
59 return;
60 }
61 }
62
63 auto item = new QStandardItem;
64 auto addProperty = [&] (const QByteArray &key) {
65 item->setData(message.value(key), mRoles[key]);
66 };
67 item->setData(QDateTime::currentDateTime(), mRoles["timestamp"]);
68 addProperty("type");
69 addProperty("subtype");
70 addProperty("message");
71 addProperty("details");
72 addProperty("resource");
73 addProperty("entities");
74 insertRow(0, item);
75}
76
diff --git a/framework/src/logmodel.h b/framework/src/logmodel.h
new file mode 100644
index 00000000..73909e87
--- /dev/null
+++ b/framework/src/logmodel.h
@@ -0,0 +1,41 @@
1/*
2 Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net>
3 Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com>
4
5 This library is free software; you can redistribute it and/or modify it
6 under the terms of the GNU Library General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or (at your
8 option) any later version.
9
10 This library is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 02110-1301, USA.
19*/
20
21#pragma once
22#include "kube_export.h"
23
24#include <QStandardItemModel>
25#include <QVariantMap>
26#include <fabric.h>
27
28class KUBE_EXPORT LogModel : public QStandardItemModel
29{
30 Q_OBJECT
31
32public:
33 LogModel(QObject *parent = Q_NULLPTR);
34 ~LogModel();
35
36 Q_INVOKABLE void insert(const QVariantMap &);
37
38private:
39 // QSharedPointer<Kube::Fabric::Listener> mListener;
40 QHash<QByteArray, int> mRoles;
41};
diff --git a/views/log/main.qml b/views/log/main.qml
index f4f20582..066f4295 100644
--- a/views/log/main.qml
+++ b/views/log/main.qml
@@ -86,7 +86,7 @@ ApplicationWindow {
86 { 86 {
87 "type": Kube.Notifications.error, 87 "type": Kube.Notifications.error,
88 "subtype": Kube.Notifications.loginError, 88 "subtype": Kube.Notifications.loginError,
89 message: "merge1", 89 message: "Failed to login",
90 resource: "resource1", 90 resource: "resource1",
91 entities: [] 91 entities: []
92 } 92 }
@@ -96,7 +96,7 @@ ApplicationWindow {
96 { 96 {
97 "type": Kube.Notifications.error, 97 "type": Kube.Notifications.error,
98 "subtype": Kube.Notifications.hostNotFoundError, 98 "subtype": Kube.Notifications.hostNotFoundError,
99 message: "merge1", 99 message: "Host Not Found",
100 resource: "resource1", 100 resource: "resource1",
101 entities: [] 101 entities: []
102 } 102 }
@@ -106,7 +106,7 @@ ApplicationWindow {
106 { 106 {
107 "type": Kube.Notifications.error, 107 "type": Kube.Notifications.error,
108 "subtype": Kube.Notifications.connectionError, 108 "subtype": Kube.Notifications.connectionError,
109 message: "merge1", 109 message: "connection error",
110 resource: "resource1", 110 resource: "resource1",
111 entities: [] 111 entities: []
112 } 112 }
@@ -118,7 +118,7 @@ ApplicationWindow {
118 { 118 {
119 "type": Kube.Notifications.error, 119 "type": Kube.Notifications.error,
120 "subtype": Kube.Notifications.transmissionError, 120 "subtype": Kube.Notifications.transmissionError,
121 message: "merge1", 121 message: "transmission error with mail uid",
122 resource: "resource1", 122 resource: "resource1",
123 entities: [mail_uid] 123 entities: [mail_uid]
124 } 124 }
@@ -130,7 +130,7 @@ ApplicationWindow {
130 { 130 {
131 "type": Kube.Notifications.error, 131 "type": Kube.Notifications.error,
132 "subtype": Kube.Notifications.transmissionError, 132 "subtype": Kube.Notifications.transmissionError,
133 message: "merge1", 133 message: "transmission error with another mail uid",
134 resource: "resource1", 134 resource: "resource1",
135 entities: [mail2_uid] 135 entities: [mail2_uid]
136 } 136 }
@@ -140,7 +140,7 @@ ApplicationWindow {
140 { 140 {
141 "type": Kube.Notifications.error, 141 "type": Kube.Notifications.error,
142 "subtype": "customSubType", 142 "subtype": "customSubType",
143 message: "merge1", 143 message: "custom subtype error",
144 resource: "resource1", 144 resource: "resource1",
145 entities: [] 145 entities: []
146 } 146 }
diff --git a/views/log/qml/View.qml b/views/log/qml/View.qml
index 30b87bcc..b710267d 100644
--- a/views/log/qml/View.qml
+++ b/views/log/qml/View.qml
@@ -61,27 +61,7 @@ Controls1.SplitView {
61 } 61 }
62 root.pendingNotification = true 62 root.pendingNotification = true
63 } 63 }
64 64 logModel.insert(message)
65 var error = {
66 timestamp: new Date(),
67 message: message.message,
68 details: message.details,
69 resource: message.resource,
70 // TODO: if we passed entities as a list, it would get
71 // converted to a ListModel, in all likelihood because of
72 // ListDelegate, which we should rewrite in C++
73 entities: {elements: message.entities}
74 }
75
76 if (logModel.count > 0) {
77 var lastEntry = logModel.get(0)
78 //Merge if we get an entry of the same subtype
79 if (lastEntry.subtype && lastEntry.subtype == message.subtype) {
80 logModel.set(0, {type: message.type, subtype: message.subtype, errors: [error].concat(lastEntry.errors)})
81 return
82 }
83 }
84 logModel.insert(0, {type: message.type, subtype: message.subtype, errors: [error]})
85 } 65 }
86 } 66 }
87 67
@@ -99,25 +79,23 @@ Controls1.SplitView {
99 79
100 clip: true 80 clip: true
101 81
102 model: ListModel { 82 model: Kube.LogModel {
103 id: logModel 83 id: logModel
104 objectName: "logModel" 84 objectName: "logModel"
105 } 85 }
106 86
107 onCurrentItemChanged: { 87 onCurrentItemChanged: {
108 var error = currentItem.currentData.errors.get(0) 88 if (!!currentItem.currentData.resource) {
109 if (!!error.resource) { 89 details.resourceId = currentItem.currentData.resource
110 details.resourceId = error.resource
111 } 90 }
112 details.message = error.message + "\n" + error.details 91 details.message = currentItem.currentData.message + "\n" + currentItem.currentData.details
113 details.timestamp = error.timestamp 92 details.timestamp = currentItem.currentData.timestamp
93 details.entities = currentItem.currentData.entities
114 if (!!currentItem.currentData.subtype) { 94 if (!!currentItem.currentData.subtype) {
115 details.subtype = currentItem.currentData.subtype 95 details.subtype = currentItem.currentData.subtype
116 } else { 96 } else {
117 details.subtype = "" 97 details.subtype = ""
118 } 98 }
119
120 details.entities = error.entities
121 } 99 }
122 100
123 delegate: Kube.ListDelegate { 101 delegate: Kube.ListDelegate {
@@ -149,7 +127,7 @@ Controls1.SplitView {
149 maximumLineCount: 1 127 maximumLineCount: 1
150 elide: Text.ElideRight 128 elide: Text.ElideRight
151 color: Kube.Colors.disabledTextColor 129 color: Kube.Colors.disabledTextColor
152 text: model.errors.get(0).message 130 text: model.message
153 } 131 }
154 132
155 Kube.Label { 133 Kube.Label {
@@ -160,7 +138,7 @@ Controls1.SplitView {
160 bottom: parent.bottom 138 bottom: parent.bottom
161 rightMargin: Kube.Units.smallSpacing 139 rightMargin: Kube.Units.smallSpacing
162 } 140 }
163 text: Qt.formatDateTime(model.errors.get(0).timestamp, " hh:mm:ss dd MMM yyyy") 141 text: Qt.formatDateTime(model.timestamp, " hh:mm:ss dd MMM yyyy")
164 font.italic: true 142 font.italic: true
165 color: Kube.Colors.disabledTextColor 143 color: Kube.Colors.disabledTextColor
166 font.pointSize: Kube.Units.smallFontSize 144 font.pointSize: Kube.Units.smallFontSize
@@ -196,7 +174,7 @@ Controls1.SplitView {
196 property string resourceId: details.resourceId 174 property string resourceId: details.resourceId
197 property string accountId: retriever.currentData ? retriever.currentData.accountId : "" 175 property string accountId: retriever.currentData ? retriever.currentData.accountId : ""
198 property string accountName: retriever.currentData ? retriever.currentData.name : "" 176 property string accountName: retriever.currentData ? retriever.currentData.name : ""
199 property var entities: details.entities 177 property string entityId: details.entities.length != 0 ? details.entities[0] : ""
200 178
201 function getComponent(subtype) { 179 function getComponent(subtype) {
202 if (subtype == Kube.Notifications.loginError) { 180 if (subtype == Kube.Notifications.loginError) {
@@ -364,6 +342,7 @@ Controls1.SplitView {
364 Component { 342 Component {
365 id: transmissionErrorComponent 343 id: transmissionErrorComponent
366 Item { 344 Item {
345 id: componentRoot
367 Column { 346 Column {
368 anchors { 347 anchors {
369 top: parent.top 348 top: parent.top
@@ -383,7 +362,7 @@ Controls1.SplitView {
383 362
384 Repeater { 363 Repeater {
385 model: Kube.MailListModel { 364 model: Kube.MailListModel {
386 entityId: entities.elements[0] 365 entityId: componentRoot.parent ? componentRoot.parent.entityId : ""
387 } 366 }
388 delegate: Column { 367 delegate: Column {
389 id: subHeadline 368 id: subHeadline
diff --git a/views/log/tests/tst_logview.qml b/views/log/tests/tst_logview.qml
index c64e4335..8f733b6c 100644
--- a/views/log/tests/tst_logview.qml
+++ b/views/log/tests/tst_logview.qml
@@ -36,29 +36,33 @@ TestCase {
36 function test_logview() { 36 function test_logview() {
37 var listModel = findChild(logView, "logModel"); 37 var listModel = findChild(logView, "logModel");
38 verify(listModel) 38 verify(listModel)
39 compare(listModel.count, 0) 39 compare(listModel.rowCount(), 0)
40 //ignore progress 40 //ignore progress
41 Kube.Fabric.postMessage(Kube.Messages.progressNotification, {}) 41 Kube.Fabric.postMessage(Kube.Messages.progressNotification, {})
42 compare(listModel.count, 0) 42 compare(listModel.rowCount(), 0)
43 43
44 Kube.Fabric.postMessage(Kube.Messages.notification, {type: Kube.Notifications.info, message: "foobar", resource: "resource"}) 44 Kube.Fabric.postMessage(Kube.Messages.notification, {type: Kube.Notifications.info, message: "foobar", resource: "resource"})
45 compare(listModel.count, 1) 45 compare(listModel.rowCount(), 1)
46 compare(logView.pendingError, false) 46 compare(logView.pendingError, false)
47 47
48 Kube.Fabric.postMessage(Kube.Messages.notification, {"type": Kube.Notifications.error, message: "foobar", resource: "resource"}) 48 Kube.Fabric.postMessage(Kube.Messages.notification, {"type": Kube.Notifications.error, message: "foobar", resource: "resource"})
49 compare(listModel.count, 2) 49 compare(listModel.rowCount(), 2)
50 compare(logView.pendingError, true) 50 compare(logView.pendingError, true)
51 compare(listModel.get(0).type, Kube.Notifications.error) 51
52 compare(listModel.get(0).errors.count, 1) 52 //FIXME test the model contents again
53 compare(listModel.get(0).errors.get(0).message, "foobar") 53 //Yes, this is ridiculous
54 compare(listModel.get(0).errors.get(0).resource, "resource") 54 // compare(listModel.data(listModel.index(0, 0), Kube.LogModel.Type), Kube.Notifications.error)
55 // compare(listModel.get(0).errors.rowCount(), 1)
56 // compare(listModel.get(0).errors.get(0).message, "foobar")
57 // compare(listModel.get(0).errors.get(0).resource, "resource")
55 58
56 Kube.Fabric.postMessage(Kube.Messages.notification, {"type": Kube.Notifications.error, "subtype": "merge", message: "merge1", resource: "resource1"}) 59 Kube.Fabric.postMessage(Kube.Messages.notification, {"type": Kube.Notifications.error, "subtype": "merge", message: "merge1", resource: "resource1"})
57 compare(listModel.count, 3) 60 compare(listModel.rowCount(), 3)
58 Kube.Fabric.postMessage(Kube.Messages.notification, {"type": Kube.Notifications.error, "subtype": "merge", message: "merge2", resource: "resource2"}) 61 Kube.Fabric.postMessage(Kube.Messages.notification, {"type": Kube.Notifications.error, "subtype": "merge", message: "merge2", resource: "resource2"})
59 compare(listModel.count, 3) 62 compare(listModel.rowCount(), 3)
60 compare(listModel.get(0).errors.count, 2) 63
61 compare(listModel.get(0).errors.get(0).message, "merge2") 64 // compare(listModel.get(0).errors.rowCount(), 2)
62 compare(listModel.get(0).errors.get(0).resource, "resource2") 65 // compare(listModel.get(0).errors.get(0).message, "merge2")
66 // compare(listModel.get(0).errors.get(0).resource, "resource2")
63 } 67 }
64} 68}