Fauxton: refactor ActiveTasks - do not use a model as a collection, directly operate on the collection which gets filtered for the view - remove the view which acted as layer to fetch collections from the model and passed it to a view - remove not used html-template - format code
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/cd8286ec Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/cd8286ec Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/cd8286ec Branch: refs/heads/1.6.x Commit: cd8286ec6efde1ba98e98d1c9e1a8a5720e6242f Parents: 7b80bc2 Author: Robert Kowalski <[email protected]> Authored: Sun Apr 6 23:15:16 2014 +0200 Committer: Robert Kowalski <[email protected]> Committed: Thu May 15 21:17:09 2014 +0200 ---------------------------------------------------------------------- src/Makefile.am | 1 - src/fauxton/app/addons/activetasks/resources.js | 96 ++------- src/fauxton/app/addons/activetasks/routes.js | 24 +-- .../addons/activetasks/templates/detail.html | 21 -- .../app/addons/activetasks/templates/table.html | 2 +- .../app/addons/activetasks/tests/viewsSpec.js | 54 +++-- src/fauxton/app/addons/activetasks/views.js | 195 ++++++++++--------- 7 files changed, 154 insertions(+), 239 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb/blob/cd8286ec/src/Makefile.am ---------------------------------------------------------------------- diff --git a/src/Makefile.am b/src/Makefile.am index 1e3515d..240b4e0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,7 +43,6 @@ FAUXTON_FILES = \ fauxton/app/addons/activetasks/base.js \ fauxton/app/addons/activetasks/resources.js \ fauxton/app/addons/activetasks/routes.js \ - fauxton/app/addons/activetasks/templates/detail.html \ fauxton/app/addons/activetasks/templates/table.html \ fauxton/app/addons/activetasks/templates/tabledetail.html \ fauxton/app/addons/activetasks/templates/tabs.html \ http://git-wip-us.apache.org/repos/asf/couchdb/blob/cd8286ec/src/fauxton/app/addons/activetasks/resources.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/activetasks/resources.js b/src/fauxton/app/addons/activetasks/resources.js index 3c5a513..3d1798f 100644 --- a/src/fauxton/app/addons/activetasks/resources.js +++ b/src/fauxton/app/addons/activetasks/resources.js @@ -22,93 +22,23 @@ function (app, backbone, Fauxton) { apiv = app.versionAPI; app.taskSortBy = 'type'; - Active.Task = Backbone.Model.extend({ - initialize: function() { - this.set({"id": this.get('pid')}); - } - }); -// ALL THE TASKS - Active.Tasks = Backbone.Model.extend({ - alltypes: { - "all": "All tasks", - "replication": "Replication", - "database_compaction":" Database Compaction", - "indexer": "Indexer", - "view_compaction": "View Compaction" - }, - documentation: "_active_tasks", - url: function (context) { - if (context === "apiurl"){ - return window.location.origin + '/_active_tasks'; - } else { - return app.host + '/_active_tasks'; - } - }, - fetch: function (options) { - var fetchoptions = options || {}; - fetchoptions.cache = false; - return Backbone.Model.prototype.fetch.call(this, fetchoptions); - }, - parse: function(resp){ - var types = this.getUniqueTypes(resp), - that = this; - - var typeCollections = _.reduce(types, function (collection, val, key) { - collection[key] = new Active.AllTasks(that.sortThis(resp, key)); - return collection; - }, {}); - - typeCollections.all = new Active.AllTasks(resp); - - this.set(typeCollections); //now set them all to the model - }, - getUniqueTypes: function(resp){ - var types = this.alltypes; - - _.each(resp, function(type){ - if( typeof(types[type.type]) === "undefined"){ - types[type.type] = type.type.replace(/_/g,' '); - } - },this); + Active.events = {}; + _.extend(Active.events, Backbone.Events); - this.alltypes = types; - return types; - }, - sortThis: function(resp, type){ - return _.filter(resp, function(item) { return item.type === type; }); - }, - changeView: function (view){ - this.set({ - "currentView": view - }); - }, - getCurrentViewData: function(){ - var currentView = this.get('currentView'); - return this.get(currentView); - }, - getDatabaseCompactions: function(){ - return this.get('databaseCompactions'); - }, - getIndexes: function(){ - return this.get('indexes'); - }, - getViewCompactions: function(){ - return this.get('viewCompactions'); - } + Active.Task = Backbone.Model.extend({ + idAttribute: "pid" }); -//ALL TASKS - -//NEW IDEA. Lets make this extremely generic, so if there are new weird tasks, they get sorted and collected. - Active.AllTasks = Backbone.Collection.extend({ model: Active.Task, - sortByColumn: function(colName) { + + sortByColumn: function (colName) { app.taskSortBy = colName; this.sort(); }, - comparator: function(item) { + + comparator: function (item) { var value = app.taskSortBy, values; @@ -122,6 +52,16 @@ function (app, backbone, Fauxton) { } return item.get(value); + }, + + documentation: "_active_tasks", + + url: function (context) { + if (context === "apiurl") { + return window.location.origin + "/_active_tasks"; + } else { + return app.host + "/_active_tasks"; + } } }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/cd8286ec/src/fauxton/app/addons/activetasks/routes.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/activetasks/routes.js b/src/fauxton/app/addons/activetasks/routes.js index dcb2efe..cdc5a01 100644 --- a/src/fauxton/app/addons/activetasks/routes.js +++ b/src/fauxton/app/addons/activetasks/routes.js @@ -19,7 +19,7 @@ define([ function (app, FauxtonAPI, Activetasks, Views) { - var ActiveTasksRouteObject = FauxtonAPI.RouteObject.extend({ + var ActiveTasksRouteObject = FauxtonAPI.RouteObject.extend({ layout: "with_sidebar", routes: { @@ -34,26 +34,22 @@ function (app, FauxtonAPI, Activetasks, Views) { ], apiUrl: function () { - return [this.newtasks.url("apiurl"), this.newtasks.documentation]; + return [this.allTasks.url("apiurl"), this.allTasks.documentation]; }, roles: ["_admin"], - defaultView: function (id) { - this.newtasks = new Activetasks.Tasks({ - currentView: "all", - id:'activeTasks' - }); - - this.setView("#sidebar-content", new Views.TabMenu({ - currentView: "all", - model: this.newtasks - })); + initialize: function () { + this.allTasks = new Activetasks.AllTasks(); + }, - this.setView("#dashboard-content", new Views.DataSection({ - model: this.newtasks, + defaultView: function () { + this.setView("#dashboard-content", new Views.View({ + collection: this.allTasks, currentView: "all" })); + + this.setView("#sidebar-content", new Views.TabMenu({})); } }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/cd8286ec/src/fauxton/app/addons/activetasks/templates/detail.html ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/activetasks/templates/detail.html b/src/fauxton/app/addons/activetasks/templates/detail.html deleted file mode 100644 index 5e53129..0000000 --- a/src/fauxton/app/addons/activetasks/templates/detail.html +++ /dev/null @@ -1,21 +0,0 @@ -<!-- -Licensed under the Apache License, Version 2.0 (the "License"); you may not -use this file except in compliance with the License. You may obtain a copy of -the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -License for the specific language governing permissions and limitations under -the License. ---> - -<div class="progress progress-striped active"> - <div class="bar" style="width: <%=model.get("progress")%>%;"><%=model.get("progress")%>%</div> -</div> -<p> - <%= model.get("type").replace('_',' ')%> on - <%= model.get("node")%> -</p> http://git-wip-us.apache.org/repos/asf/couchdb/blob/cd8286ec/src/fauxton/app/addons/activetasks/templates/table.html ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/activetasks/templates/table.html b/src/fauxton/app/addons/activetasks/templates/table.html index 84dbccd..a8cbd52 100644 --- a/src/fauxton/app/addons/activetasks/templates/table.html +++ b/src/fauxton/app/addons/activetasks/templates/table.html @@ -45,7 +45,7 @@ the License. </tr> </thead> - <tbody id="tasks_go_here"> + <tbody class="js-tasks-go-here"> </tbody> http://git-wip-us.apache.org/repos/asf/couchdb/blob/cd8286ec/src/fauxton/app/addons/activetasks/tests/viewsSpec.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/activetasks/tests/viewsSpec.js b/src/fauxton/app/addons/activetasks/tests/viewsSpec.js index 5da2c3f..19c5b65 100644 --- a/src/fauxton/app/addons/activetasks/tests/viewsSpec.js +++ b/src/fauxton/app/addons/activetasks/tests/viewsSpec.js @@ -10,11 +10,11 @@ // License for the specific language governing permissions and limitations under // the License. define([ - 'api', - 'addons/activetasks/views', - 'addons/activetasks/resources', - 'testUtils' -], function (FauxtonAPI, Views, Models, testUtils) { + 'api', + 'addons/activetasks/views', + 'addons/activetasks/resources', + 'testUtils' +], function (FauxtonAPI, Views, Activetasks, testUtils) { var assert = testUtils.assert, ViewSandbox = testUtils.ViewSandbox; @@ -22,15 +22,7 @@ define([ var tabMenu; beforeEach(function () { - var newtasks = new Models.Tasks({ - currentView: "all", - id:'activeTasks' - }); - - tabMenu = new Views.TabMenu({ - currentView: "all", - model: newtasks - }); + tabMenu = new Views.TabMenu({}); }); describe("on change polling rate", function () { @@ -73,50 +65,48 @@ define([ }); describe('on request by type', function () { - var viewSandbox; + var viewSandbox, mainView; beforeEach(function () { + + mainView = new Views.View({ + collection: new Activetasks.AllTasks(), + currentView: "all" + }); + viewSandbox = new ViewSandbox(); viewSandbox.renderView(tabMenu); + viewSandbox.renderView(mainView); }); afterEach(function () { viewSandbox.remove(); }); - it("should change model view", function () { - var spy = sinon.spy(tabMenu.model, 'changeView'); + it("should set the filter the main-view", function () { var $rep = tabMenu.$('li[data-type="replication"]'); $rep.click(); - assert.ok(spy.calledOnce); + assert.equal("replication", mainView.filter); }); it("should set correct active tab", function () { - var spy = sinon.spy(tabMenu.model, 'changeView'); var $rep = tabMenu.$('li[data-type="replication"]'); $rep.click(); assert.ok($rep.hasClass('active')); }); - }); }); describe('DataSection', function () { - var viewSandbox, dataSection; + var viewSandbox, mainView; beforeEach(function () { - var newtasks = new Models.Tasks({ - currentView: "all", - id:'activeTasks' - }); - newtasks.parse([]); - - dataSection = new Views.DataSection({ - currentView: "all", - model: newtasks + mainView = new Views.View({ + collection: new Activetasks.AllTasks(), + currentView: "all" }); viewSandbox = new ViewSandbox(); - viewSandbox.renderView(dataSection); + viewSandbox.renderView(mainView); }); afterEach(function () { @@ -127,7 +117,7 @@ define([ it('Should set polling interval', function () { var spy = sinon.spy(window, 'setInterval'); - dataSection.setPolling(); + mainView.setPolling(); assert.ok(spy.calledOnce); }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/cd8286ec/src/fauxton/app/addons/activetasks/views.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/activetasks/views.js b/src/fauxton/app/addons/activetasks/views.js index 22918a6..83ef861 100644 --- a/src/fauxton/app/addons/activetasks/views.js +++ b/src/fauxton/app/addons/activetasks/views.js @@ -11,16 +11,16 @@ // the License. define([ - "app", - "api", - "addons/activetasks/resources" + "app", + "api", + "addons/activetasks/resources" ], -function (app, FauxtonAPI, activetasks) { +function (app, FauxtonAPI, ActiveTasks) { var Views = {}, Events = {}, - pollingInfo ={ + pollingInfo = { rate: "5", intervalId: null }; @@ -28,23 +28,110 @@ function (app, FauxtonAPI, activetasks) { Views.Events = _.extend(Events, Backbone.Events); + Views.View = FauxtonAPI.View.extend({ + tagName: "table", + + className: "table table-bordered table-striped active-tasks", + + template: "addons/activetasks/templates/table", + + events: { + "click th": "sortByType" + }, + + filter: "all", + + initialize: function (options) { + this.listenTo(ActiveTasks.events, "tasks:filter", this.filterAndRender); + this.listenTo(this.collection, "reset", this.render); + }, + + beforeRender: function () { + this.filterAndInsertView(this.filter); + }, + + filterAndRender: function (view) { + this.filter = view; + this.render(); + }, + + filterAndInsertView: function () { + var that = this; + this.removeView(".js-tasks-go-here"); + + this.collection.forEach(function (item) { + if (that.filter !== "all" && item.get("type") !== that.filter) { + return; + } + var view = new Views.TableDetail({ + model: item + }); + this.insertView(".js-tasks-go-here", view); + }, this); + }, + + afterRender: function () { + Events.bind("update:poll", this.setPolling, this); + this.setPolling(); + }, + + establish: function () { + return [this.collection.fetch()]; + }, + + serialize: function () { + return { + currentView: this.currentView, + collection: this.collection + }; + }, + + sortByType: function (e) { + var currentTarget = e.currentTarget, + datatype = this.$(currentTarget).attr("data-type"); + + this.collection.sortByColumn(datatype); + this.render(); + }, + + setPolling: function () { + var collection = this.collection; + + clearInterval(pollingInfo.intervalId); + pollingInfo.intervalId = setInterval(function () { + collection.fetch({reset: true}); + }, pollingInfo.rate * 1000); + }, + + cleanup: function () { + clearInterval(pollingInfo.intervalId); + } + }); + Views.TabMenu = FauxtonAPI.View.extend({ template: "addons/activetasks/templates/tabs", + events: { "click .task-tabs li": "requestByType", "change #pollingRange": "changePollInterval" }, - establish: function(){ - return [this.model.fetch({reset: true})]; - }, - serialize: function(){ + + serialize: function () { return { - filters: this.model.alltypes + filters: { + "all": "All tasks", + "replication": "Replication", + "database_compaction":" Database Compaction", + "indexer": "Indexer", + "view_compaction": "View Compaction" + } }; }, + afterRender: function(){ this.$('.task-tabs').find('li').eq(0).addClass('active'); }, + changePollInterval: function(e){ var range = this.$(e.currentTarget).val(); this.$('label[for="pollingRange"] span').text(range); @@ -63,96 +150,20 @@ function (app, FauxtonAPI, activetasks) { this.$('.task-tabs').find('li').removeClass('active'); this.$(currentTarget).addClass('active'); - this.model.changeView(datatype); - } - }); - Views.DataSection = FauxtonAPI.View.extend({ - showData: function(){ - var currentData = this.model.getCurrentViewData(); - - if (this.dataView) { - this.dataView.update(currentData, this.model.get('currentView').replace('_',' ')); - } else { - this.dataView = this.insertView( new Views.TableData({ - collection: currentData, - currentView: this.model.get('currentView').replace('_',' ') - })); - } - }, - showDataAndRender: function () { - this.showData(); - this.dataView.render(); - }, - - beforeRender: function () { - this.showData(); - }, - establish: function(){ - return [this.model.fetch()]; - }, - setPolling: function(){ - var that = this; - clearInterval(pollingInfo.intervalId); - pollingInfo.intervalId = setInterval(function() { - that.establish(); - }, pollingInfo.rate*1000); - }, - cleanup: function(){ - clearInterval(pollingInfo.intervalId); - }, - afterRender: function(){ - this.listenTo(this.model, "change", this.showDataAndRender); - Events.bind('update:poll', this.setPolling, this); - this.setPolling(); - } - }); - - Views.TableData = FauxtonAPI.View.extend({ - tagName: "table", - className: "table table-bordered table-striped active-tasks", - template: "addons/activetasks/templates/table", - events: { - "click th": "sortByType" - }, - initialize: function(){ - this.currentView = this.options.currentView; - }, - sortByType: function(e){ - var currentTarget = e.currentTarget, - datatype = $(currentTarget).attr("data-type"); - - this.collection.sortByColumn(datatype); - this.render(); - }, - serialize: function(){ - return { - currentView: this.currentView, - collection: this.collection - }; - }, - - update: function (collection, currentView) { - this.collection = collection; - this.currentView = currentView; - }, - - beforeRender: function(){ - //iterate over the collection to add each - this.collection.forEach(function(item) { - this.insertView("#tasks_go_here", new Views.TableDetail({ - model: item - })); - }, this); + ActiveTasks.events.trigger("tasks:filter", datatype); } }); Views.TableDetail = FauxtonAPI.View.extend({ tagName: 'tr', + template: "addons/activetasks/templates/tabledetail", + initialize: function(){ this.type = this.model.get('type'); }, + getObject: function(){ var objectField = this.model.get('database'); if (this.type === "replication"){ @@ -160,6 +171,7 @@ function (app, FauxtonAPI, activetasks) { } return objectField; }, + getProgress: function(){ var progress = ""; if (this.type === "indexer"){ @@ -182,6 +194,7 @@ function (app, FauxtonAPI, activetasks) { return progress; }, + serialize: function(){ return { model: this.model, @@ -191,7 +204,5 @@ function (app, FauxtonAPI, activetasks) { } }); - - return Views; });
