diff options
Diffstat (limited to 'views/log/qml/View.qml')
-rw-r--r-- | views/log/qml/View.qml | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/views/log/qml/View.qml b/views/log/qml/View.qml new file mode 100644 index 00000000..4ae1a67c --- /dev/null +++ b/views/log/qml/View.qml | |||
@@ -0,0 +1,329 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Michael Bohlender, <michael.bohlender@kdemail.net> | ||
3 | * Copyright (C) 2017 Christian Mollekopf, <mollekopf@kolabsys.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | import QtQuick 2.4 | ||
21 | import QtQuick.Layouts 1.1 | ||
22 | import QtQuick.Controls 1.3 as Controls | ||
23 | import QtQuick.Controls 2.0 as Controls2 | ||
24 | import org.kube.framework 1.0 as Kube | ||
25 | |||
26 | Controls.SplitView { | ||
27 | id: root | ||
28 | |||
29 | property bool pendingError: false; | ||
30 | |||
31 | Controls2.StackView.onActivated: { | ||
32 | root.pendingError = false; | ||
33 | //Always select the latest notification | ||
34 | listView.currentIndex = 0 | ||
35 | } | ||
36 | |||
37 | Item { | ||
38 | id: accountList | ||
39 | width: parent.width/3 | ||
40 | Layout.fillHeight: true | ||
41 | |||
42 | Kube.Listener { | ||
43 | filter: Kube.Messages.notification | ||
44 | onMessageReceived: { | ||
45 | if (message.type == Kube.Notifications.error) { | ||
46 | root.pendingError = true | ||
47 | } | ||
48 | var error = {timestamp: new Date(), message: message.message, details: message.details, resource: message.resource} | ||
49 | if (logModel.count > 0) { | ||
50 | var lastEntry = logModel.get(0) | ||
51 | //Merge if we get an entry of the same subtype | ||
52 | if (lastEntry.subtype && lastEntry.subtype == message.subtype) { | ||
53 | logModel.set(0, {type: message.type, subtype: message.subtype, errors: [error].concat(lastEntry.errors)}) | ||
54 | return | ||
55 | } | ||
56 | } | ||
57 | logModel.insert(0, {type: message.type, subtype: message.subtype, errors: [error]}) | ||
58 | } | ||
59 | } | ||
60 | |||
61 | Kube.Label { | ||
62 | anchors.centerIn: parent | ||
63 | visible: listView.count == 0 | ||
64 | text: qsTr("Nothing here...") | ||
65 | } | ||
66 | |||
67 | Kube.ListView { | ||
68 | id: listView | ||
69 | anchors { | ||
70 | fill: parent | ||
71 | } | ||
72 | |||
73 | clip: true | ||
74 | |||
75 | model: ListModel { | ||
76 | id: logModel | ||
77 | objectName: "logModel" | ||
78 | } | ||
79 | |||
80 | onCurrentItemChanged: { | ||
81 | var error = currentItem.currentData.errors.get(0) | ||
82 | if (!!error.resource) { | ||
83 | details.resourceId = error.resource | ||
84 | } | ||
85 | details.message = error.message + "\n" + error.details | ||
86 | details.timestamp = error.timestamp | ||
87 | if (!!currentItem.currentData.subtype) { | ||
88 | details.subtype = currentItem.currentData.subtype | ||
89 | } else { | ||
90 | details.subtype = "" | ||
91 | } | ||
92 | } | ||
93 | |||
94 | delegate: Kube.ListDelegate { | ||
95 | border.color: Kube.Colors.buttonColor | ||
96 | border.width: 1 | ||
97 | Kube.Label { | ||
98 | id: description | ||
99 | anchors { | ||
100 | top: parent.top | ||
101 | topMargin: Kube.Units.smallSpacing | ||
102 | left: parent.left | ||
103 | leftMargin: Kube.Units.largeSpacing | ||
104 | } | ||
105 | height: Kube.Units.gridUnit | ||
106 | width: parent.width - Kube.Units.largeSpacing * 2 | ||
107 | text: model.type == Kube.Notifications.error ? qsTr("Error") : qsTr("Info") | ||
108 | } | ||
109 | |||
110 | Kube.Label { | ||
111 | id: message | ||
112 | anchors { | ||
113 | topMargin: Kube.Units.smallSpacing | ||
114 | top: description.bottom | ||
115 | left: parent.left | ||
116 | leftMargin: Kube.Units.largeSpacing | ||
117 | } | ||
118 | height: Kube.Units.gridUnit | ||
119 | width: parent.width - Kube.Units.largeSpacing * 2 | ||
120 | maximumLineCount: 1 | ||
121 | elide: Text.ElideRight | ||
122 | color: Kube.Colors.disabledTextColor | ||
123 | text: model.errors.get(0).message | ||
124 | } | ||
125 | |||
126 | Kube.Label { | ||
127 | id: date | ||
128 | |||
129 | anchors { | ||
130 | right: parent.right | ||
131 | bottom: parent.bottom | ||
132 | rightMargin: Kube.Units.smallSpacing | ||
133 | } | ||
134 | text: Qt.formatDateTime(model.errors.get(0).timestamp, " hh:mm:ss dd MMM yyyy") | ||
135 | font.italic: true | ||
136 | color: Kube.Colors.disabledTextColor | ||
137 | font.pointSize: Kube.Units.smallFontSize | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | Item { | ||
143 | id: details | ||
144 | property string subtype: "" | ||
145 | property date timestamp | ||
146 | property string message: "" | ||
147 | property string resourceId: "" | ||
148 | |||
149 | Kube.ModelIndexRetriever { | ||
150 | id: retriever | ||
151 | model: Kube.AccountsModel { | ||
152 | resourceId: details.resourceId | ||
153 | } | ||
154 | } | ||
155 | |||
156 | Loader { | ||
157 | id: detailsLoader | ||
158 | visible: message != "" | ||
159 | clip: true | ||
160 | anchors { | ||
161 | fill: parent | ||
162 | margins: Kube.Units.largeSpacing | ||
163 | } | ||
164 | property date timestamp: details.timestamp | ||
165 | property string message: details.message | ||
166 | property string resourceId: details.resourceId | ||
167 | property string accountId: retriever.currentData ? retriever.currentData.accountId : "" | ||
168 | property string accountName: retriever.currentData ? retriever.currentData.name : "" | ||
169 | |||
170 | function getComponent(subtype) { | ||
171 | if (subtype == Kube.Notifications.loginError) { | ||
172 | return loginErrorComponent | ||
173 | } | ||
174 | if (subtype == Kube.Notifications.hostNotFoundError) { | ||
175 | return hostNotFoundErrorComponent | ||
176 | } | ||
177 | if (subtype == Kube.Notifications.connectionError) { | ||
178 | return hostNotFoundErrorComponent | ||
179 | } | ||
180 | return detailsComponent | ||
181 | } | ||
182 | |||
183 | sourceComponent: getComponent(details.subtype) | ||
184 | } | ||
185 | } | ||
186 | |||
187 | Component { | ||
188 | id: detailsComponent | ||
189 | Rectangle { | ||
190 | color: Kube.Colors.viewBackgroundColor | ||
191 | GridLayout { | ||
192 | id: gridLayout | ||
193 | Layout.minimumWidth: 0 | ||
194 | anchors { | ||
195 | top: parent.top | ||
196 | left: parent.left | ||
197 | right: parent.right | ||
198 | } | ||
199 | columns: 2 | ||
200 | Kube.Label { | ||
201 | text: qsTr("Account:") | ||
202 | visible: accountName | ||
203 | } | ||
204 | Kube.Label { | ||
205 | Layout.fillWidth: true | ||
206 | text: accountName | ||
207 | visible: accountName | ||
208 | elide: Text.ElideRight | ||
209 | } | ||
210 | Kube.Label { | ||
211 | text: qsTr("Account Id:") | ||
212 | visible: accountId | ||
213 | } | ||
214 | Kube.Label { | ||
215 | text: accountId | ||
216 | visible: accountId | ||
217 | Layout.fillWidth: true | ||
218 | elide: Text.ElideRight | ||
219 | } | ||
220 | Kube.Label { | ||
221 | text: qsTr("Resource Id:") | ||
222 | visible: resourceId | ||
223 | } | ||
224 | Kube.Label { | ||
225 | text: resourceId | ||
226 | visible: resourceId | ||
227 | Layout.fillWidth: true | ||
228 | elide: Text.ElideRight | ||
229 | } | ||
230 | Kube.Label { | ||
231 | text: qsTr("Timestamp:") | ||
232 | } | ||
233 | Kube.Label { | ||
234 | text: Qt.formatDateTime(timestamp, " hh:mm:ss dd MMM yyyy") | ||
235 | Layout.fillWidth: true | ||
236 | elide: Text.ElideRight | ||
237 | } | ||
238 | Kube.Label { | ||
239 | text: qsTr("Message:") | ||
240 | Layout.alignment: Qt.AlignTop | ||
241 | } | ||
242 | Kube.Label { | ||
243 | text: message | ||
244 | Layout.fillWidth: true | ||
245 | wrapMode: Text.Wrap | ||
246 | } | ||
247 | Item { | ||
248 | Layout.columnSpan: 2 | ||
249 | Layout.fillHeight: true | ||
250 | Layout.fillWidth: true | ||
251 | } | ||
252 | } | ||
253 | |||
254 | Kube.SelectableItem { | ||
255 | layout: gridLayout | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | |||
260 | Component { | ||
261 | id: loginErrorComponent | ||
262 | Item { | ||
263 | Column { | ||
264 | anchors { | ||
265 | top: parent.top | ||
266 | left: parent.left | ||
267 | right: parent.right | ||
268 | } | ||
269 | spacing: Kube.Units.largeSpacing | ||
270 | Column { | ||
271 | Kube.Heading { | ||
272 | id: heading | ||
273 | text: qsTr("Failed to login") | ||
274 | color: Kube.Colors.warningColor | ||
275 | } | ||
276 | |||
277 | Kube.Label { | ||
278 | id: subHeadline | ||
279 | text: accountName + ": " + qsTr("Please check your credentials.") | ||
280 | color: Kube.Colors.disabledTextColor | ||
281 | wrapMode: Text.Wrap | ||
282 | } | ||
283 | } | ||
284 | Kube.Button { | ||
285 | text: qsTr("Change Password") | ||
286 | onClicked: { | ||
287 | Kube.Fabric.postMessage(Kube.Messages.componentDone, {}) | ||
288 | Kube.Fabric.postMessage(Kube.Messages.requestLogin, {accountId: accountId}) | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | } | ||
293 | } | ||
294 | |||
295 | Component { | ||
296 | id: hostNotFoundErrorComponent | ||
297 | Item { | ||
298 | Column { | ||
299 | anchors { | ||
300 | top: parent.top | ||
301 | left: parent.left | ||
302 | right: parent.right | ||
303 | } | ||
304 | spacing: Kube.Units.largeSpacing | ||
305 | Column { | ||
306 | Kube.Heading { | ||
307 | id: heading | ||
308 | text: qsTr("Host not found") | ||
309 | color: Kube.Colors.warningColor | ||
310 | } | ||
311 | |||
312 | Kube.Label { | ||
313 | id: subHeadline | ||
314 | text: accountName + ": " + qsTr("Please check your network connection and settings.") | ||
315 | color: Kube.Colors.disabledTextColor | ||
316 | wrapMode: Text.Wrap | ||
317 | } | ||
318 | } | ||
319 | Kube.Button { | ||
320 | text: qsTr("Account settings") | ||
321 | onClicked: { | ||
322 | Kube.Fabric.postMessage(Kube.Messages.componentDone, {}) | ||
323 | Kube.Fabric.postMessage(Kube.Messages.requestAccountsConfiguration, {}) | ||
324 | } | ||
325 | } | ||
326 | } | ||
327 | } | ||
328 | } | ||
329 | } | ||