From 32fc68b9dfb7808edaea59c3abdd79a4925fea58 Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Sat, 14 Feb 2015 11:18:21 +0100 Subject: [PATCH] UI Cleanup - Updated System, Tags and Wanted subtrees. --- src/UI/System/Backup/BackupCollection.js | 4 +- src/UI/System/Backup/BackupEmptyView.js | 4 +- src/UI/System/Backup/BackupLayout.js | 86 ++++---- src/UI/System/Backup/BackupTypeCell.js | 13 +- src/UI/System/Info/About/AboutView.js | 5 +- .../System/Info/DiskSpace/DiskSpaceLayout.js | 58 +++--- .../Info/DiskSpace/DiskSpacePathCell.js | 10 +- src/UI/System/Info/Health/HealthCell.js | 4 +- src/UI/System/Info/Health/HealthLayout.js | 58 +++--- src/UI/System/Info/Health/HealthOkView.js | 4 +- src/UI/System/Info/Health/HealthWikiCell.js | 9 +- src/UI/System/Info/MoreInfo/MoreInfoView.js | 4 +- src/UI/System/Info/SystemInfoLayout.js | 6 +- src/UI/System/Logs/Files/ContentsModel.js | 5 +- src/UI/System/Logs/Files/ContentsView.js | 4 +- src/UI/System/Logs/Files/DownloadLogCell.js | 4 +- src/UI/System/Logs/Files/FilenameCell.js | 4 +- src/UI/System/Logs/Files/LogFileCollection.js | 1 + src/UI/System/Logs/Files/LogFileLayout.js | 117 +++++++---- src/UI/System/Logs/Files/Row.js | 12 +- src/UI/System/Logs/LogsCollection.js | 97 +++++---- src/UI/System/Logs/LogsLayout.js | 38 ++-- .../Logs/Table/Details/LogDetailsView.js | 4 +- src/UI/System/Logs/Table/LogLevelCell.js | 4 +- src/UI/System/Logs/Table/LogRow.js | 12 +- src/UI/System/Logs/Table/LogTimeCell.js | 4 +- src/UI/System/Logs/Table/LogsTableLayout.js | 182 ++++++++++------- .../System/Logs/Updates/LogFileCollection.js | 1 + src/UI/System/StatusModel.js | 11 +- src/UI/System/SystemLayout.js | 59 ++++-- src/UI/System/SystemLayoutTemplate.hbs | 2 +- src/UI/System/Task/ExecuteTaskCell.js | 21 +- src/UI/System/Task/NextExecutionCell.js | 21 +- src/UI/System/Task/TaskCollection.js | 4 +- src/UI/System/Task/TaskIntervalCell.js | 11 +- src/UI/System/Task/TaskLayout.js | 77 ++++--- src/UI/System/Update/EmptyView.js | 4 +- src/UI/System/Update/UpdateItemView.js | 22 +- src/UI/System/Update/UpdateLayout.js | 20 +- src/UI/Tags/TagCollection.js | 8 +- src/UI/Tags/TagHelpers.js | 36 ++-- src/UI/Wanted/Cutoff/CutoffUnmetCollection.js | 94 +++++---- src/UI/Wanted/Cutoff/CutoffUnmetLayout.js | 180 +++++++++------- src/UI/Wanted/Missing/MissingCollection.js | 92 +++++---- src/UI/Wanted/Missing/MissingLayout.js | 193 ++++++++++-------- src/UI/Wanted/WantedLayout.js | 42 ++-- 46 files changed, 1008 insertions(+), 643 deletions(-) diff --git a/src/UI/System/Backup/BackupCollection.js b/src/UI/System/Backup/BackupCollection.js index e476face0..5bee1fc35 100644 --- a/src/UI/System/Backup/BackupCollection.js +++ b/src/UI/System/Backup/BackupCollection.js @@ -4,10 +4,12 @@ var BackupModel = require('./BackupModel'); module.exports = PageableCollection.extend({ url : window.NzbDrone.ApiRoot + '/system/backup', model : BackupModel, + state : { sortKey : 'time', order : 1, pageSize : 100000 }, - mode : 'client' + + mode : 'client' }); \ No newline at end of file diff --git a/src/UI/System/Backup/BackupEmptyView.js b/src/UI/System/Backup/BackupEmptyView.js index 8e283dd0c..a86ba42bc 100644 --- a/src/UI/System/Backup/BackupEmptyView.js +++ b/src/UI/System/Backup/BackupEmptyView.js @@ -1,3 +1,5 @@ var Marionette = require('marionette'); -module.exports = Marionette.ItemView.extend({template : 'System/Backup/BackupEmptyViewTemplate'}); \ No newline at end of file +module.exports = Marionette.ItemView.extend({ + template : 'System/Backup/BackupEmptyViewTemplate' +}); \ No newline at end of file diff --git a/src/UI/System/Backup/BackupLayout.js b/src/UI/System/Backup/BackupLayout.js index c740b5c87..6961762cf 100644 --- a/src/UI/System/Backup/BackupLayout.js +++ b/src/UI/System/Backup/BackupLayout.js @@ -10,55 +10,68 @@ var LoadingView = require('../../Shared/LoadingView'); var ToolbarLayout = require('../../Shared/Toolbar/ToolbarLayout'); module.exports = Marionette.Layout.extend({ - template : 'System/Backup/BackupLayoutTemplate', - regions : { + template : 'System/Backup/BackupLayoutTemplate', + + regions : { backups : '#x-backups', toolbar : '#x-backup-toolbar' }, - columns : [{ - name : 'type', - label : '', - sortable : false, - cell : BackupTypeCell - }, { - name : 'this', - label : 'Name', - sortable : false, - cell : BackupFilenameCell - }, { - name : 'time', - label : 'Time', - sortable : false, - cell : RelativeDateCell - }], - leftSideButtons : { + + columns : [ + { + name : 'type', + label : '', + sortable : false, + cell : BackupTypeCell + }, + { + name : 'this', + label : 'Name', + sortable : false, + cell : BackupFilenameCell + }, + { + name : 'time', + label : 'Time', + sortable : false, + cell : RelativeDateCell + } + ], + + leftSideButtons : { type : 'default', storeState : false, collapse : false, - items : [{ - title : 'Backup', - icon : 'icon-file-text', - command : 'backup', - properties : {type : 'manual'}, - successMessage : 'Database and settings were backed up successfully', - errorMessage : 'Backup Failed!' - }] + items : [ + { + title : 'Backup', + icon : 'icon-file-text', + command : 'backup', + properties : { type : 'manual' }, + successMessage : 'Database and settings were backed up successfully', + errorMessage : 'Backup Failed!' + } + ] }, - initialize : function(){ + + initialize : function() { this.backupCollection = new BackupCollection(); + this.listenTo(this.backupCollection, 'sync', this._showBackups); this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete); }, - onRender : function(){ + + onRender : function() { this._showToolbar(); this.backups.show(new LoadingView()); + this.backupCollection.fetch(); }, - _showBackups : function(){ - if(this.backupCollection.length === 0) { + + _showBackups : function() { + if (this.backupCollection.length === 0) { this.backups.show(new EmptyView()); - } - else { + } else { this.backups.show(new Backgrid.Grid({ columns : this.columns, collection : this.backupCollection, @@ -66,14 +79,15 @@ module.exports = Marionette.Layout.extend({ })); } }, - _showToolbar : function(){ + + _showToolbar : function() { this.toolbar.show(new ToolbarLayout({ left : [this.leftSideButtons], context : this })); }, - _commandComplete : function(options){ - if(options.command.get('name') === 'backup') { + _commandComplete : function(options) { + if (options.command.get('name') === 'backup') { this.backupCollection.fetch(); } } diff --git a/src/UI/System/Backup/BackupTypeCell.js b/src/UI/System/Backup/BackupTypeCell.js index 0c131c70b..bb7a74d03 100644 --- a/src/UI/System/Backup/BackupTypeCell.js +++ b/src/UI/System/Backup/BackupTypeCell.js @@ -2,20 +2,25 @@ var NzbDroneCell = require('../../Cells/NzbDroneCell'); module.exports = NzbDroneCell.extend({ className : 'backup-type-cell', - render : function(){ + + render : function() { this.$el.empty(); + var icon = 'icon-time'; var title = 'Scheduled'; + var type = this.model.get(this.column.get('name')); - if(type === 'manual') { + + if (type === 'manual') { icon = 'icon-book'; title = 'Manual'; - } - else if(type === 'update') { + } else if (type === 'update') { icon = 'icon-retweet'; title = 'Before update'; } + this.$el.html(''.format(icon, title)); + return this; } }); \ No newline at end of file diff --git a/src/UI/System/Info/About/AboutView.js b/src/UI/System/Info/About/AboutView.js index 585f498db..494b9a3ef 100644 --- a/src/UI/System/Info/About/AboutView.js +++ b/src/UI/System/Info/About/AboutView.js @@ -2,8 +2,9 @@ var Marionette = require('marionette'); var StatusModel = require('../../StatusModel'); module.exports = Marionette.ItemView.extend({ - template : 'System/Info/About/AboutViewTemplate', - initialize : function(){ + template : 'System/Info/About/AboutViewTemplate', + + initialize : function() { this.model = StatusModel; } }); \ No newline at end of file diff --git a/src/UI/System/Info/DiskSpace/DiskSpaceLayout.js b/src/UI/System/Info/DiskSpace/DiskSpaceLayout.js index 1a5dcba81..bd3470750 100644 --- a/src/UI/System/Info/DiskSpace/DiskSpaceLayout.js +++ b/src/UI/System/Info/DiskSpace/DiskSpaceLayout.js @@ -1,4 +1,4 @@ -var vent = require('vent'); +var vent = require('vent'); var Marionette = require('marionette'); var Backgrid = require('backgrid'); var DiskSpaceCollection = require('./DiskSpaceCollection'); @@ -7,35 +7,47 @@ var DiskSpacePathCell = require('./DiskSpacePathCell'); var FileSizeCell = require('../../../Cells/FileSizeCell'); module.exports = Marionette.Layout.extend({ - template : 'System/Info/DiskSpace/DiskSpaceLayoutTemplate', - regions : {grid : '#x-grid'}, - columns : [{ - name : 'path', - label : 'Location', - cell : DiskSpacePathCell, - sortable : false - }, { - name : 'freeSpace', - label : 'Free Space', - cell : FileSizeCell, - sortable : false - }, { - name : 'totalSpace', - label : 'Total Space', - cell : FileSizeCell, - sortable : false - }], - initialize : function(){ + template : 'System/Info/DiskSpace/DiskSpaceLayoutTemplate', + + regions : { + grid : '#x-grid' + }, + + columns : [ + { + name : 'path', + label : 'Location', + cell : DiskSpacePathCell, + sortable : false + }, + { + name : 'freeSpace', + label : 'Free Space', + cell : FileSizeCell, + sortable : false + }, + { + name : 'totalSpace', + label : 'Total Space', + cell : FileSizeCell, + sortable : false + } + ], + + initialize : function() { this.collection = new DiskSpaceCollection(); this.listenTo(this.collection, 'sync', this._showTable); }, - onRender : function(){ + + onRender : function() { this.grid.show(new LoadingView()); }, - onShow : function(){ + + onShow : function() { this.collection.fetch(); }, - _showTable : function(){ + + _showTable : function() { this.grid.show(new Backgrid.Grid({ row : Backgrid.Row, columns : this.columns, diff --git a/src/UI/System/Info/DiskSpace/DiskSpacePathCell.js b/src/UI/System/Info/DiskSpace/DiskSpacePathCell.js index 49132e56d..de2ceb9b6 100644 --- a/src/UI/System/Info/DiskSpace/DiskSpacePathCell.js +++ b/src/UI/System/Info/DiskSpace/DiskSpacePathCell.js @@ -2,15 +2,21 @@ var Backgrid = require('backgrid'); module.exports = Backgrid.Cell.extend({ className : 'disk-space-path-cell', - render : function(){ + + render : function() { this.$el.empty(); + var path = this.model.get('path'); var label = this.model.get('label'); + var contents = path; - if(label) { + + if (label) { contents += ' ({0})'.format(label); } + this.$el.html(contents); + return this; } }); \ No newline at end of file diff --git a/src/UI/System/Info/Health/HealthCell.js b/src/UI/System/Info/Health/HealthCell.js index cad0bc84e..191b356d1 100644 --- a/src/UI/System/Info/Health/HealthCell.js +++ b/src/UI/System/Info/Health/HealthCell.js @@ -2,9 +2,11 @@ var NzbDroneCell = require('../../../Cells/NzbDroneCell'); module.exports = NzbDroneCell.extend({ className : 'log-level-cell', - render : function(){ + + render : function() { var level = this._getValue(); this.$el.html(''.format(this._getValue().toLowerCase(), level)); + return this; } }); \ No newline at end of file diff --git a/src/UI/System/Info/Health/HealthLayout.js b/src/UI/System/Info/Health/HealthLayout.js index 37a41e9db..bc2bc33eb 100644 --- a/src/UI/System/Info/Health/HealthLayout.js +++ b/src/UI/System/Info/Health/HealthLayout.js @@ -6,37 +6,47 @@ var HealthWikiCell = require('./HealthWikiCell'); var HealthOkView = require('./HealthOkView'); module.exports = Marionette.Layout.extend({ - template : 'System/Info/Health/HealthLayoutTemplate', - regions : {grid : '#x-health-grid'}, - columns : [{ - name : 'type', - label : '', - cell : HealthCell, - sortable : false - }, { - name : 'message', - label : 'Message', - cell : 'string', - sortable : false - }, { - name : 'wikiUrl', - label : '', - cell : HealthWikiCell, - sortable : false - }], - initialize : function(){ + template : 'System/Info/Health/HealthLayoutTemplate', + + regions : { + grid : '#x-health-grid' + }, + + columns : [ + { + name : 'type', + label : '', + cell : HealthCell, + sortable : false + }, + { + name : 'message', + label : 'Message', + cell : 'string', + sortable : false + }, + { + name : 'wikiUrl', + label : '', + cell : HealthWikiCell, + sortable : false + } + ], + + initialize : function() { this.listenTo(HealthCollection, 'sync', this.render); HealthCollection.fetch(); }, - onRender : function(){ - if(HealthCollection.length === 0) { + + onRender : function() { + if (HealthCollection.length === 0) { this.grid.show(new HealthOkView()); - } - else { + } else { this._showTable(); } }, - _showTable : function(){ + + _showTable : function() { this.grid.show(new Backgrid.Grid({ row : Backgrid.Row, columns : this.columns, diff --git a/src/UI/System/Info/Health/HealthOkView.js b/src/UI/System/Info/Health/HealthOkView.js index e9ca33ff4..662d9d278 100644 --- a/src/UI/System/Info/Health/HealthOkView.js +++ b/src/UI/System/Info/Health/HealthOkView.js @@ -1,3 +1,5 @@ var Marionette = require('marionette'); -module.exports = Marionette.ItemView.extend({template : 'System/Info/Health/HealthOkViewTemplate'}); \ No newline at end of file +module.exports = Marionette.ItemView.extend({ + template : 'System/Info/Health/HealthOkViewTemplate' +}); \ No newline at end of file diff --git a/src/UI/System/Info/Health/HealthWikiCell.js b/src/UI/System/Info/Health/HealthWikiCell.js index 90a107ab5..bb93f0606 100644 --- a/src/UI/System/Info/Health/HealthWikiCell.js +++ b/src/UI/System/Info/Health/HealthWikiCell.js @@ -3,9 +3,12 @@ var Backgrid = require('backgrid'); module.exports = Backgrid.UriCell.extend({ className : 'wiki-link-cell', - title : 'Read the Wiki for more information', - text : 'Wiki', - render : function(){ + + title : 'Read the Wiki for more information', + + text : 'Wiki', + + render : function() { this.$el.empty(); var rawValue = this.model.get(this.column.get('name')); var formattedValue = this.formatter.fromRaw(rawValue, this.model); diff --git a/src/UI/System/Info/MoreInfo/MoreInfoView.js b/src/UI/System/Info/MoreInfo/MoreInfoView.js index 10808bbdc..0217ed742 100644 --- a/src/UI/System/Info/MoreInfo/MoreInfoView.js +++ b/src/UI/System/Info/MoreInfo/MoreInfoView.js @@ -1,3 +1,5 @@ var Marionette = require('marionette'); -module.exports = Marionette.ItemView.extend({template : 'System/Info/MoreInfo/MoreInfoViewTemplate'}); \ No newline at end of file +module.exports = Marionette.ItemView.extend({ + template : 'System/Info/MoreInfo/MoreInfoViewTemplate' +}); \ No newline at end of file diff --git a/src/UI/System/Info/SystemInfoLayout.js b/src/UI/System/Info/SystemInfoLayout.js index f72cb5cdf..0b56318ea 100644 --- a/src/UI/System/Info/SystemInfoLayout.js +++ b/src/UI/System/Info/SystemInfoLayout.js @@ -7,13 +7,15 @@ var MoreInfoView = require('./MoreInfo/MoreInfoView'); module.exports = Marionette.Layout.extend({ template : 'System/Info/SystemInfoLayoutTemplate', - regions : { + + regions : { about : '#about', diskSpace : '#diskspace', health : '#health', moreInfo : '#more-info' }, - onRender : function(){ + + onRender : function() { this.health.show(new HealthLayout()); this.diskSpace.show(new DiskSpaceLayout()); this.about.show(new AboutView()); diff --git a/src/UI/System/Logs/Files/ContentsModel.js b/src/UI/System/Logs/Files/ContentsModel.js index 28baa40c3..c9c47b1bb 100644 --- a/src/UI/System/Logs/Files/ContentsModel.js +++ b/src/UI/System/Logs/Files/ContentsModel.js @@ -1,10 +1,11 @@ var Backbone = require('backbone'); module.exports = Backbone.Model.extend({ - url : function(){ + url : function() { return this.get('contentsUrl'); }, - parse : function(contents){ + + parse : function(contents) { var response = {}; response.contents = contents; return response; diff --git a/src/UI/System/Logs/Files/ContentsView.js b/src/UI/System/Logs/Files/ContentsView.js index 1b645bf44..6b5b9e067 100644 --- a/src/UI/System/Logs/Files/ContentsView.js +++ b/src/UI/System/Logs/Files/ContentsView.js @@ -1,3 +1,5 @@ var Marionette = require('marionette'); -module.exports = Marionette.ItemView.extend({template : 'System/Logs/Files/ContentsViewTemplate'}); \ No newline at end of file +module.exports = Marionette.ItemView.extend({ + template : 'System/Logs/Files/ContentsViewTemplate' +}); \ No newline at end of file diff --git a/src/UI/System/Logs/Files/DownloadLogCell.js b/src/UI/System/Logs/Files/DownloadLogCell.js index bdf066b1f..8be2d0176 100644 --- a/src/UI/System/Logs/Files/DownloadLogCell.js +++ b/src/UI/System/Logs/Files/DownloadLogCell.js @@ -2,9 +2,11 @@ var NzbDroneCell = require('../../../Cells/NzbDroneCell'); module.exports = NzbDroneCell.extend({ className : 'download-log-cell', - render : function(){ + + render : function() { this.$el.empty(); this.$el.html('Download'.format(this.cellValue)); + return this; } }); \ No newline at end of file diff --git a/src/UI/System/Logs/Files/FilenameCell.js b/src/UI/System/Logs/Files/FilenameCell.js index ec6c40cc7..aedbb8cfb 100644 --- a/src/UI/System/Logs/Files/FilenameCell.js +++ b/src/UI/System/Logs/Files/FilenameCell.js @@ -2,9 +2,11 @@ var NzbDroneCell = require('../../../Cells/NzbDroneCell'); module.exports = NzbDroneCell.extend({ className : 'log-filename-cell', - render : function(){ + + render : function() { var filename = this._getValue(); this.$el.html(filename); + return this; } }); \ No newline at end of file diff --git a/src/UI/System/Logs/Files/LogFileCollection.js b/src/UI/System/Logs/Files/LogFileCollection.js index 211c68aac..590dda677 100644 --- a/src/UI/System/Logs/Files/LogFileCollection.js +++ b/src/UI/System/Logs/Files/LogFileCollection.js @@ -4,6 +4,7 @@ var LogFileModel = require('./LogFileModel'); module.exports = Backbone.Collection.extend({ url : window.NzbDrone.ApiRoot + '/log/file', model : LogFileModel, + state : { sortKey : 'lastWriteTime', order : 1 diff --git a/src/UI/System/Logs/Files/LogFileLayout.js b/src/UI/System/Logs/Files/LogFileLayout.js index 310f68892..419098f3a 100644 --- a/src/UI/System/Logs/Files/LogFileLayout.js +++ b/src/UI/System/Logs/Files/LogFileLayout.js @@ -12,63 +12,79 @@ var LoadingView = require('../../../Shared/LoadingView'); require('../../../jQuery/jquery.spin'); module.exports = Marionette.Layout.extend({ - template : 'System/Logs/Files/LogFileLayoutTemplate', - regions : { + template : 'System/Logs/Files/LogFileLayoutTemplate', + + regions : { toolbar : '#x-toolbar', grid : '#x-grid', contents : '#x-contents' }, - columns : [{ - name : 'filename', - label : 'Filename', - cell : FilenameCell, - sortable : false - }, { - name : 'lastWriteTime', - label : 'Last Write Time', - cell : RelativeDateCell, - sortable : false - }, { - name : 'downloadUrl', - label : '', - cell : DownloadLogCell, - sortable : false - }], - initialize : function(options){ + + columns : [ + { + name : 'filename', + label : 'Filename', + cell : FilenameCell, + sortable : false + }, + { + name : 'lastWriteTime', + label : 'Last Write Time', + cell : RelativeDateCell, + sortable : false + }, + { + name : 'downloadUrl', + label : '', + cell : DownloadLogCell, + sortable : false + } + ], + + initialize : function(options) { this.collection = options.collection; this.deleteFilesCommand = options.deleteFilesCommand; + this.listenTo(vent, vent.Commands.ShowLogFile, this._fetchLogFileContents); this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete); this.listenTo(this.collection, 'sync', this._collectionSynced); + this.collection.fetch(); }, - onShow : function(){ + + onShow : function() { this._showToolbar(); this._showTable(); }, - _showToolbar : function(){ + + _showToolbar : function() { var leftSideButtons = { type : 'default', storeState : false, - items : [{ - title : 'Refresh', - icon : 'icon-refresh', - ownerContext : this, - callback : this._refreshTable - }, { - title : 'Delete Log Files', - icon : 'icon-trash', - command : this.deleteFilesCommand, - successMessage : 'Log files have been deleted', - errorMessage : 'Failed to delete log files' - }] + items : [ + { + title : 'Refresh', + icon : 'icon-refresh', + ownerContext : this, + callback : this._refreshTable + }, + { + title : 'Delete Log Files', + icon : 'icon-trash', + command : this.deleteFilesCommand, + successMessage : 'Log files have been deleted', + errorMessage : 'Failed to delete log files' + } + ] }; + this.toolbar.show(new ToolbarLayout({ left : [leftSideButtons], context : this })); }, - _showTable : function(){ + + _showTable : function() { this.grid.show(new Backgrid.Grid({ row : LogFileRow, columns : this.columns, @@ -76,32 +92,43 @@ module.exports = Marionette.Layout.extend({ className : 'table table-hover' })); }, - _collectionSynced : function(){ - if(!this.collection.any()) { + + _collectionSynced : function() { + if (!this.collection.any()) { return; } + var model = this.collection.first(); - this._fetchLogFileContents({model : model}); + this._fetchLogFileContents({ model : model }); }, - _fetchLogFileContents : function(options){ + + _fetchLogFileContents : function(options) { this.contents.show(new LoadingView()); + var model = options.model; var contentsModel = new ContentsModel(model.toJSON()); + this.listenToOnce(contentsModel, 'sync', this._showDetails); - contentsModel.fetch({dataType : 'text'}); + + contentsModel.fetch({ dataType : 'text' }); }, - _showDetails : function(model){ - this.contents.show(new ContentsView({model : model})); + + _showDetails : function(model) { + this.contents.show(new ContentsView({ model : model })); }, - _refreshTable : function(buttonContext){ + + _refreshTable : function(buttonContext) { this.contents.close(); var promise = this.collection.fetch(); - if(buttonContext) { + + //Would be nice to spin the icon on the refresh button + if (buttonContext) { buttonContext.ui.icon.spinForPromise(promise); } }, - _commandComplete : function(options){ - if(options.command.get('name') === this.deleteFilesCommand.toLowerCase()) { + + _commandComplete : function(options) { + if (options.command.get('name') === this.deleteFilesCommand.toLowerCase()) { this._refreshTable(); } } diff --git a/src/UI/System/Logs/Files/Row.js b/src/UI/System/Logs/Files/Row.js index dc5fce9fb..01e6bd55a 100644 --- a/src/UI/System/Logs/Files/Row.js +++ b/src/UI/System/Logs/Files/Row.js @@ -2,9 +2,13 @@ var vent = require('vent'); var Backgrid = require('backgrid'); module.exports = Backgrid.Row.extend({ - className : 'log-file-row', - events : {"click" : '_showDetails'}, - _showDetails : function(){ - vent.trigger(vent.Commands.ShowLogFile, {model : this.model}); + className : 'log-file-row', + + events : { + 'click' : '_showDetails' + }, + + _showDetails : function() { + vent.trigger(vent.Commands.ShowLogFile, { model : this.model }); } }); \ No newline at end of file diff --git a/src/UI/System/Logs/LogsCollection.js b/src/UI/System/Logs/LogsCollection.js index 78b34a77b..c233a9d63 100644 --- a/src/UI/System/Logs/LogsCollection.js +++ b/src/UI/System/Logs/LogsCollection.js @@ -3,43 +3,62 @@ var LogsModel = require('./LogsModel'); var AsFilteredCollection = require('../../Mixins/AsFilteredCollection'); var AsPersistedStateCollection = require('../../Mixins/AsPersistedStateCollection'); -module.exports = (function(){ - var collection = PagableCollection.extend({ - url : window.NzbDrone.ApiRoot + '/log', - model : LogsModel, - tableName : 'logs', - state : { - pageSize : 50, - sortKey : 'time', - order : 1 - }, - queryParams : { - totalPages : null, - totalRecords : null, - pageSize : 'pageSize', - sortKey : 'sortKey', - order : 'sortDir', - directions : { - "-1" : 'asc', - "1" : 'desc' - } - }, - filterModes : { - "all" : [null, null], - "info" : ['level', 'Info'], - "warn" : ['level', 'Warn'], - "error" : ['level', 'Error'] - }, - parseState : function(resp, queryParams, state){ - return {totalRecords : resp.totalRecords}; - }, - parseRecords : function(resp){ - if(resp) { - return resp.records; - } - return resp; +var collection = PagableCollection.extend({ + url : window.NzbDrone.ApiRoot + '/log', + model : LogsModel, + tableName : 'logs', + + state : { + pageSize : 50, + sortKey : 'time', + order : 1 + }, + + queryParams : { + totalPages : null, + totalRecords : null, + pageSize : 'pageSize', + sortKey : 'sortKey', + order : 'sortDir', + directions : { + '-1' : 'asc', + '1' : 'desc' } - }); - collection = AsFilteredCollection.apply(collection); - return AsPersistedStateCollection.apply(collection); -}).call(this); \ No newline at end of file + }, + + // Filter Modes + filterModes : { + "all" : [ + null, + null + ], + "info" : [ + 'level', + 'Info' + ], + "warn" : [ + 'level', + 'Warn' + ], + "error" : [ + 'level', + 'Error' + ] + }, + + parseState : function(resp, queryParams, state) { + return { totalRecords : resp.totalRecords }; + }, + + parseRecords : function(resp) { + if (resp) { + return resp.records; + } + + return resp; + } +}); + +collection = AsFilteredCollection.apply(collection); + +module.exports = AsPersistedStateCollection.apply(collection); \ No newline at end of file diff --git a/src/UI/System/Logs/LogsLayout.js b/src/UI/System/Logs/LogsLayout.js index 54314406c..d064cff64 100644 --- a/src/UI/System/Logs/LogsLayout.js +++ b/src/UI/System/Logs/LogsLayout.js @@ -5,46 +5,56 @@ var LogFileCollection = require('./Files/LogFileCollection'); var UpdateLogFileCollection = require('./Updates/LogFileCollection'); module.exports = Marionette.Layout.extend({ - template : 'System/Logs/LogsLayoutTemplate', - ui : { + template : 'System/Logs/LogsLayoutTemplate', + + ui : { tableTab : '.x-table-tab', filesTab : '.x-files-tab', updateFilesTab : '.x-update-files-tab' }, - regions : { + + regions : { table : '#table', files : '#files', updateFiles : '#update-files' }, - events : { - "click .x-table-tab" : '_showTable', - "click .x-files-tab" : '_showFiles', - "click .x-update-files-tab" : '_showUpdateFiles' + + events : { + 'click .x-table-tab' : '_showTable', + 'click .x-files-tab' : '_showFiles', + 'click .x-update-files-tab' : '_showUpdateFiles' }, - onShow : function(){ + + onShow : function() { this._showTable(); }, - _showTable : function(e){ - if(e) { + + _showTable : function(e) { + if (e) { e.preventDefault(); } + this.ui.tableTab.tab('show'); this.table.show(new LogsTableLayout()); }, - _showFiles : function(e){ - if(e) { + + _showFiles : function(e) { + if (e) { e.preventDefault(); } + this.ui.filesTab.tab('show'); this.files.show(new LogsFileLayout({ collection : new LogFileCollection(), deleteFilesCommand : 'deleteLogFiles' })); }, - _showUpdateFiles : function(e){ - if(e) { + + _showUpdateFiles : function(e) { + if (e) { e.preventDefault(); } + this.ui.updateFilesTab.tab('show'); this.updateFiles.show(new LogsFileLayout({ collection : new UpdateLogFileCollection(), diff --git a/src/UI/System/Logs/Table/Details/LogDetailsView.js b/src/UI/System/Logs/Table/Details/LogDetailsView.js index 223335fcd..dcdadcf0b 100644 --- a/src/UI/System/Logs/Table/Details/LogDetailsView.js +++ b/src/UI/System/Logs/Table/Details/LogDetailsView.js @@ -1,4 +1,6 @@ var vent = require('vent'); var Marionette = require('marionette'); -module.exports = Marionette.ItemView.extend({template : 'System/Logs/Table/Details/LogDetailsViewTemplate'}); \ No newline at end of file +module.exports = Marionette.ItemView.extend({ + template : 'System/Logs/Table/Details/LogDetailsViewTemplate' +}); \ No newline at end of file diff --git a/src/UI/System/Logs/Table/LogLevelCell.js b/src/UI/System/Logs/Table/LogLevelCell.js index e8231569a..2d1d06746 100644 --- a/src/UI/System/Logs/Table/LogLevelCell.js +++ b/src/UI/System/Logs/Table/LogLevelCell.js @@ -2,9 +2,11 @@ var NzbDroneCell = require('../../../Cells/NzbDroneCell'); module.exports = NzbDroneCell.extend({ className : 'log-level-cell', - render : function(){ + + render : function() { var level = this._getValue(); this.$el.html(''.format(this._getValue().toLowerCase(), level)); + return this; } }); \ No newline at end of file diff --git a/src/UI/System/Logs/Table/LogRow.js b/src/UI/System/Logs/Table/LogRow.js index c91e2a2bf..c8cf6eb97 100644 --- a/src/UI/System/Logs/Table/LogRow.js +++ b/src/UI/System/Logs/Table/LogRow.js @@ -2,9 +2,13 @@ var vent = require('vent'); var Backgrid = require('backgrid'); module.exports = Backgrid.Row.extend({ - className : 'log-row', - events : {"click" : '_showDetails'}, - _showDetails : function(){ - vent.trigger(vent.Commands.ShowLogDetails, {model : this.model}); + className : 'log-row', + + events : { + 'click' : '_showDetails' + }, + + _showDetails : function() { + vent.trigger(vent.Commands.ShowLogDetails, { model : this.model }); } }); \ No newline at end of file diff --git a/src/UI/System/Logs/Table/LogTimeCell.js b/src/UI/System/Logs/Table/LogTimeCell.js index 09e76d315..3f8091058 100644 --- a/src/UI/System/Logs/Table/LogTimeCell.js +++ b/src/UI/System/Logs/Table/LogTimeCell.js @@ -4,9 +4,11 @@ var UiSettings = require('../../../Shared/UiSettingsModel'); module.exports = NzbDroneCell.extend({ className : 'log-time-cell', - render : function(){ + + render : function() { var date = moment(this._getValue()); this.$el.html('{0}'.format(date.format(UiSettings.time(true, false)), date.format(UiSettings.longDateTime(true)))); + return this; } }); \ No newline at end of file diff --git a/src/UI/System/Logs/Table/LogsTableLayout.js b/src/UI/System/Logs/Table/LogsTableLayout.js index 9aaf80575..a43e39dee 100644 --- a/src/UI/System/Logs/Table/LogsTableLayout.js +++ b/src/UI/System/Logs/Table/LogsTableLayout.js @@ -11,126 +11,164 @@ var LoadingView = require('../../../Shared/LoadingView'); require('../../../jQuery/jquery.spin'); module.exports = Marionette.Layout.extend({ - template : 'System/Logs/Table/LogsTableLayoutTemplate', - regions : { + template : 'System/Logs/Table/LogsTableLayoutTemplate', + + regions : { grid : '#x-grid', toolbar : '#x-toolbar', pager : '#x-pager' }, - attributes : {id : 'logs-screen'}, - columns : [{ - name : 'level', - label : '', - sortable : true, - cell : LogLevelCell - }, { - name : 'logger', - label : 'Component', - sortable : true, - cell : Backgrid.StringCell.extend({className : 'log-logger-cell'}) - }, { - name : 'message', - label : 'Message', - sortable : false, - cell : Backgrid.StringCell.extend({className : 'log-message-cell'}) - }, { - name : 'time', - label : 'Time', - cell : LogTimeCell - }], - initialize : function(){ + + attributes : { + id : 'logs-screen' + }, + + columns : [ + { + name : 'level', + label : '', + sortable : true, + cell : LogLevelCell + }, + { + name : 'logger', + label : 'Component', + sortable : true, + cell : Backgrid.StringCell.extend({ + className : 'log-logger-cell' + }) + }, + { + name : 'message', + label : 'Message', + sortable : false, + cell : Backgrid.StringCell.extend({ + className : 'log-message-cell' + }) + }, + { + name : 'time', + label : 'Time', + cell : LogTimeCell + } + ], + + initialize : function() { this.collection = new LogCollection(); + this.listenTo(this.collection, 'sync', this._showTable); this.listenTo(vent, vent.Events.CommandComplete, this._commandComplete); }, - onRender : function(){ + + onRender : function() { this.grid.show(new LoadingView()); }, - onShow : function(){ + + onShow : function() { this._showToolbar(); }, - _showTable : function(){ + + _showTable : function() { this.grid.show(new Backgrid.Grid({ row : LogRow, columns : this.columns, collection : this.collection, className : 'table table-hover' })); + this.pager.show(new GridPager({ columns : this.columns, collection : this.collection })); }, - _showToolbar : function(){ + + _showToolbar : function() { var filterButtons = { type : 'radio', storeState : true, menuKey : 'logs.filterMode', defaultAction : 'all', - items : [{ - key : 'all', - title : '', - tooltip : 'All', - icon : 'icon-circle-blank', - callback : this._setFilter - }, { - key : 'info', - title : '', - tooltip : 'Info', - icon : 'icon-info', - callback : this._setFilter - }, { - key : 'warn', - title : '', - tooltip : 'Warn', - icon : 'icon-warn', - callback : this._setFilter - }, { - key : 'error', - title : '', - tooltip : 'Error', - icon : 'icon-error', - callback : this._setFilter - }] + items : [ + { + key : 'all', + title : '', + tooltip : 'All', + icon : 'icon-circle-blank', + callback : this._setFilter + }, + { + key : 'info', + title : '', + tooltip : 'Info', + icon : 'icon-info', + callback : this._setFilter + }, + { + key : 'warn', + title : '', + tooltip : 'Warn', + icon : 'icon-warn', + callback : this._setFilter + }, + { + key : 'error', + title : '', + tooltip : 'Error', + icon : 'icon-error', + callback : this._setFilter + } + ] }; + var leftSideButtons = { type : 'default', storeState : false, - items : [{ - title : 'Refresh', - icon : 'icon-refresh', - ownerContext : this, - callback : this._refreshTable - }, { - title : 'Clear Logs', - icon : 'icon-trash', - command : 'clearLog' - }] + items : [ + { + title : 'Refresh', + icon : 'icon-refresh', + ownerContext : this, + callback : this._refreshTable + }, + { + title : 'Clear Logs', + icon : 'icon-trash', + command : 'clearLog' + } + ] }; + this.toolbar.show(new ToolbarLayout({ left : [leftSideButtons], right : [filterButtons], context : this })); }, - _refreshTable : function(buttonContext){ + + _refreshTable : function(buttonContext) { this.collection.state.currentPage = 1; - var promise = this.collection.fetch({reset : true}); - if(buttonContext) { + var promise = this.collection.fetch({ reset : true }); + + if (buttonContext) { buttonContext.ui.icon.spinForPromise(promise); } }, - _setFilter : function(buttonContext){ + + _setFilter : function(buttonContext) { var mode = buttonContext.model.get('key'); - this.collection.setFilterMode(mode, {reset : false}); + + this.collection.setFilterMode(mode, { reset : false }); + this.collection.state.currentPage = 1; - var promise = this.collection.fetch({reset : true}); - if(buttonContext) { + var promise = this.collection.fetch({ reset : true }); + + if (buttonContext) { buttonContext.ui.icon.spinForPromise(promise); } }, - _commandComplete : function(options){ - if(options.command.get('name') === 'clearlog') { + + _commandComplete : function(options) { + if (options.command.get('name') === 'clearlog') { this._refreshTable(); } } diff --git a/src/UI/System/Logs/Updates/LogFileCollection.js b/src/UI/System/Logs/Updates/LogFileCollection.js index 790f19049..1f957dbf1 100644 --- a/src/UI/System/Logs/Updates/LogFileCollection.js +++ b/src/UI/System/Logs/Updates/LogFileCollection.js @@ -4,6 +4,7 @@ var LogFileModel = require('./LogFileModel'); module.exports = Backbone.Collection.extend({ url : window.NzbDrone.ApiRoot + '/log/file/update', model : LogFileModel, + state : { sortKey : 'lastWriteTime', order : 1 diff --git a/src/UI/System/StatusModel.js b/src/UI/System/StatusModel.js index dc76f8459..075dd0918 100644 --- a/src/UI/System/StatusModel.js +++ b/src/UI/System/StatusModel.js @@ -1,8 +1,9 @@ var Backbone = require('backbone'); var ApiData = require('../Shared/ApiData'); -module.exports = (function(){ - var StatusModel = Backbone.Model.extend({url : window.NzbDrone.ApiRoot + '/system/status'}); - var instance = new StatusModel(ApiData.get('system/status')); - return instance; -}).call(this); \ No newline at end of file +var StatusModel = Backbone.Model.extend({ + url : window.NzbDrone.ApiRoot + '/system/status' +}); +var instance = new StatusModel(ApiData.get('system/status')); + +module.exports = instance; \ No newline at end of file diff --git a/src/UI/System/SystemLayout.js b/src/UI/System/SystemLayout.js index 6232626fd..d0c71ca09 100644 --- a/src/UI/System/SystemLayout.js +++ b/src/UI/System/SystemLayout.js @@ -1,4 +1,4 @@ -var $ = require('jquery'); +var $ = require('jquery'); var Backbone = require('backbone'); var Marionette = require('marionette'); var SystemInfoLayout = require('./Info/SystemInfoLayout'); @@ -10,22 +10,25 @@ var Messenger = require('../Shared/Messenger'); var StatusModel = require('./StatusModel'); module.exports = Marionette.Layout.extend({ - template : 'System/SystemLayoutTemplate', - regions : { + template : 'System/SystemLayoutTemplate', + + regions : { status : '#status', logs : '#logs', updates : '#updates', backup : '#backup', tasks : '#tasks' }, - ui : { + + ui : { statusTab : '.x-status-tab', logsTab : '.x-logs-tab', updatesTab : '.x-updates-tab', backupTab : '.x-backup-tab', tasksTab : '.x-tasks-tab' }, - events : { + + events : { 'click .x-status-tab' : '_showStatus', 'click .x-logs-tab' : '_showLogs', 'click .x-updates-tab' : '_showUpdates', @@ -34,8 +37,9 @@ module.exports = Marionette.Layout.extend({ 'click .x-shutdown' : '_shutdown', 'click .x-restart' : '_restart' }, - initialize : function(options){ - if(options.action) { + + initialize : function(options) { + if (options.action) { this.action = options.action.toLowerCase(); } @@ -43,7 +47,8 @@ module.exports = Marionette.Layout.extend({ authentication : StatusModel.get('authentication') }; }, - onShow : function(){ + + onShow : function() { switch (this.action) { case 'logs': this._showLogs(); @@ -61,13 +66,15 @@ module.exports = Marionette.Layout.extend({ this._showStatus(); } }, - _navigate : function(route){ + + _navigate : function(route) { Backbone.history.navigate(route, { trigger : true, replace : true }); }, - _showStatus : function (e) { + + _showStatus : function(e) { if (e) { e.preventDefault(); } @@ -76,53 +83,65 @@ module.exports = Marionette.Layout.extend({ this.ui.statusTab.tab('show'); this._navigate('system/status'); }, - _showLogs : function(e){ - if(e) { + + _showLogs : function(e) { + if (e) { e.preventDefault(); } + this.logs.show(new LogsLayout()); this.ui.logsTab.tab('show'); this._navigate('system/logs'); }, - _showUpdates : function(e){ - if(e) { + + _showUpdates : function(e) { + if (e) { e.preventDefault(); } + this.updates.show(new UpdateLayout()); this.ui.updatesTab.tab('show'); this._navigate('system/updates'); }, - _showBackup : function(e){ - if(e) { + + _showBackup : function(e) { + if (e) { e.preventDefault(); } + this.backup.show(new BackupLayout()); this.ui.backupTab.tab('show'); this._navigate('system/backup'); }, - _showTasks : function(e){ - if(e) { + + _showTasks : function(e) { + if (e) { e.preventDefault(); } + this.tasks.show(new TaskLayout()); this.ui.tasksTab.tab('show'); this._navigate('system/tasks'); }, - _shutdown : function(){ + + _shutdown : function() { $.ajax({ url : window.NzbDrone.ApiRoot + '/system/shutdown', type : 'POST' }); + Messenger.show({ message : 'Sonarr will shutdown shortly', type : 'info' }); }, - _restart : function(){ + + _restart : function() { $.ajax({ url : window.NzbDrone.ApiRoot + '/system/restart', type : 'POST' }); + Messenger.show({ message : 'Sonarr will restart shortly', type : 'info' diff --git a/src/UI/System/SystemLayoutTemplate.hbs b/src/UI/System/SystemLayoutTemplate.hbs index ecf0b418f..8d5ed70b0 100644 --- a/src/UI/System/SystemLayoutTemplate.hbs +++ b/src/UI/System/SystemLayoutTemplate.hbs @@ -1,4 +1,4 @@ -