diff --git a/server/ui-src/App.vue b/server/ui-src/App.vue index 1bb0ba1..1a92d2a 100644 --- a/server/ui-src/App.vue +++ b/server/ui-src/App.vue @@ -84,11 +84,11 @@ export default { let params = {}; this.selected = []; - let uri = 'api/messages'; + let uri = 'api/v1/messages'; if (self.search) { self.searching = true; self.items = []; - uri = 'api/search' + uri = 'api/v1/search' self.start = 0; // search is displayed on one page params['query'] = self.search; } else { @@ -104,7 +104,12 @@ export default { self.unread = response.data.unread; self.count = response.data.count; self.start = response.data.start; - self.items = response.data.items; + self.items = response.data.messages; + + if (self.items == 0 && self.start > 0) { + self.start = 0; + return self.loadMessages(); + } if (!self.scrollInPlace) { let mp = document.getElementById('message-page'); @@ -153,7 +158,7 @@ export default { let self = this; self.selected = []; - let uri = 'api/' + self.currentPath + let uri = 'api/v1/message/' + self.currentPath self.get(uri, false, function(response) { for (let i in self.items) { if (self.items[i].ID == self.currentPath) { @@ -171,14 +176,14 @@ export default { if (a.ContentID != '') { d.HTML = d.HTML.replace( new RegExp('cid:'+a.ContentID, 'g'), - window.location.origin+'/api/'+d.ID+'/part/'+a.PartID + window.location.origin+'/api/v1/message/'+d.ID+'/part/'+a.PartID ); } if (a.FileName.match(/^[a-zA-Z0-9\_\-\.]+$/)) { // some old email clients use the filename d.HTML = d.HTML.replace( new RegExp('src=(\'|")'+a.FileName+'(\'|")', 'g'), - 'src="'+window.location.origin+'/api/'+d.ID+'/part/'+a.PartID+'"' + 'src="'+window.location.origin+'/api/v1/message/'+d.ID+'/part/'+a.PartID+'"' ); } } @@ -190,14 +195,14 @@ export default { if (a.ContentID != '') { d.HTML = d.HTML.replace( new RegExp('cid:'+a.ContentID, 'g'), - window.location.origin+'/api/'+d.ID+'/part/'+a.PartID + window.location.origin+'/api/v1/message/'+d.ID+'/part/'+a.PartID ); } if (a.FileName.match(/^[a-zA-Z0-9\_\-\.]+$/)) { // some old email clients use the filename d.HTML = d.HTML.replace( new RegExp('src=(\'|")'+a.FileName+'(\'|")', 'g'), - 'src="'+window.location.origin+'/api/'+d.ID+'/part/'+a.PartID+'"' + 'src="'+window.location.origin+'/api/v1/message/'+d.ID+'/part/'+a.PartID+'"' ); } } @@ -221,48 +226,42 @@ export default { }); }, + // universal handler to delete current or selected messages + deleteMessages: function() { + let ids = []; + let self = this; + if (self.message) { + ids.push(self.message.ID); + } else { + ids = JSON.parse(JSON.stringify(self.selected)); + } + if (!ids.length) { + return false; + } + let uri = 'api/v1/messages'; + self.delete(uri, {'ids': ids}, function(response) { + window.location.hash = ""; + self.scrollInPlace = true; + self.loadMessages(); + }); + }, + deleteAll: function() { let self = this; - let uri = 'api/delete' - self.get(uri, false, function(response) { + let uri = 'api/v1/messages'; + self.delete(uri, false, function(response) { window.location.hash = ""; self.reloadMessages(); }); }, - deleteOne: function() { - let self = this; - if (!self.message) { - return false; - } - let uri = 'api/' + self.message.ID + '/delete' - self.get(uri, false, function(response) { - window.location.hash = ""; - self.scrollInPlace = true; - self.loadMessages(); - }); - }, - - deleteSelected: function() { - let self = this; - if (!self.selected.length) { - return false; - } - let uri = 'api/delete' - self.post(uri, {'ids': self.selected}, function(response) { - window.location.hash = ""; - self.scrollInPlace = true; - self.loadMessages(); - }); - }, - markUnread: function() { let self = this; if (!self.message) { return false; } - let uri = 'api/' + self.message.ID + '/unread' - self.get(uri, false, function(response) { + let uri = 'api/v1/messages'; + self.put(uri, {'read': false, 'ids': [self.message.ID]}, function(response) { window.location.hash = ""; self.scrollInPlace = true; self.loadMessages(); @@ -271,8 +270,8 @@ export default { markAllRead: function() { let self = this; - let uri = 'api/read' - self.get(uri, false, function(response) { + let uri = 'api/v1/messages' + self.put(uri, {'read': true}, function(response) { window.location.hash = ""; self.scrollInPlace = true; self.loadMessages(); @@ -284,8 +283,8 @@ export default { if (!self.selected.length) { return false; } - let uri = 'api/read' - self.post(uri, {'ids': self.selected}, function(response) { + let uri = 'api/v1/messages'; + self.put(uri, {'read': true, 'ids': self.selected}, function(response) { window.location.hash = ""; self.scrollInPlace = true; self.loadMessages(); @@ -297,8 +296,8 @@ export default { if (!self.selected.length) { return false; } - let uri = 'api/unread' - self.post(uri, {'ids': self.selected}, function(response) { + let uri = 'api/v1/messages'; + self.put(uri, {'read': false, 'ids': self.selected}, function(response) { window.location.hash = ""; self.scrollInPlace = true; self.loadMessages(); @@ -357,7 +356,8 @@ export default { } self.total++; self.unread++; - self.browserNotify("New mail from: " + response.Data.From.Address, response.Data.Subject); + let from = response.Data.From != null ? response.Data.From.Address : '[unknown]'; + self.browserNotify("New mail from: " + from, response.Data.Subject); } else if (response.Type == "prune") { // messages have been deleted, reload messages to adjust self.scrollInPlace = true; @@ -497,19 +497,19 @@ export default { - + - + Download diff --git a/server/ui-src/mixins.js b/server/ui-src/mixins.js index b69bd15..7e7976b 100644 --- a/server/ui-src/mixins.js +++ b/server/ui-src/mixins.js @@ -88,16 +88,16 @@ const commonMixins = { }, /** - * Axios Post request + * Axios POST request * * @params string url - * @params array array parameters Object/array + * @params array object/array values * @params function callback function */ - post: function (url, values, callback) { + post: function (url, data, callback) { let self = this; self.loading++; - axios.post(url, values) + axios.post(url, data) .then(callback) .catch(self.handleError) .then(function () { @@ -112,13 +112,34 @@ const commonMixins = { * Axios DELETE request (REST only) * * @params string url - * @params array array parameters Object/array + * @params array object/array values * @params function callback function */ - delete: function (url, values, callback) { + delete: function (url, data, callback) { let self = this; self.loading++; - axios.delete(url, { data: values }) + axios.delete(url, { data: data }) + .then(callback) + .catch(self.handleError) + .then(function () { + // always executed + if (self.loading > 0) { + self.loading--; + } + }); + }, + + /** + * Axios PUT request (REST only) + * + * @params string url + * @params array object/array values + * @params function callback function + */ + put: function (url, data, callback) { + let self = this; + self.loading++; + axios.put(url, data) .then(callback) .catch(self.handleError) .then(function () { diff --git a/server/ui-src/templates/Attachments.vue b/server/ui-src/templates/Attachments.vue index 07df5d8..a13cf68 100644 --- a/server/ui-src/templates/Attachments.vue +++ b/server/ui-src/templates/Attachments.vue @@ -14,8 +14,8 @@ export default {