From 298edc67fe858158cf72301f358c28ef644587b9 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 23 Oct 2012 15:31:57 +0300 Subject: [PATCH] Loading list of all available tags from backend. --- comments/app.js | 7 +++ comments/lib/comments.js | 7 +++ comments/lib/request.js | 9 ++++ comments/lib/tags.js | 18 +++++++ comments/spec/tags.spec.js | 16 +++++++ template/app/view/comments/TagEditor.js | 64 +++++++++++++++++++------ 6 files changed, 107 insertions(+), 14 deletions(-) diff --git a/comments/app.js b/comments/app.js index 19e968b7..651106c3 100644 --- a/comments/app.js +++ b/comments/app.js @@ -220,6 +220,13 @@ app.post('/auth/:sdk/:version/comments/:commentId/remove_tag', Auth.isLoggedIn, }); }); +// Returns list of all available tags +app.get('/auth/:sdk/:version/tags', function(req, res) { + new Request(req).getAllTags(function(tags) { + res.send({ success: true, tags: tags }); + }); +}); + // Marks a comment 'read' app.post('/auth/:sdk/:version/comments/:commentId/read', Auth.isLoggedIn, function(req, res) { new Request(req).markRead(req.params.commentId, function() { diff --git a/comments/lib/comments.js b/comments/lib/comments.js index 08323c4a..c628cff9 100644 --- a/comments/lib/comments.js +++ b/comments/lib/comments.js @@ -372,6 +372,13 @@ Comments.prototype = { }); }, + /** + * @inheritdoc Tags#getAll + */ + getAllTags: function(callback) { + this.tags.getAll(callback); + }, + /** * @inheritdoc Tags#add */ diff --git a/comments/lib/request.js b/comments/lib/request.js index 78a83e8e..72af7507 100644 --- a/comments/lib/request.js +++ b/comments/lib/request.js @@ -198,6 +198,15 @@ Request.prototype = { }); }, + /** + * Retrieves array of all tags. + */ + getAllTags: function(callback) { + this.db.comments().getAllTags(function(err, tags) { + callback(tags); + }); + }, + /** * Adds tag to comment. */ diff --git a/comments/lib/tags.js b/comments/lib/tags.js index 6bff2b65..7f9154cb 100644 --- a/comments/lib/tags.js +++ b/comments/lib/tags.js @@ -14,6 +14,24 @@ function Tags(db, domain) { } Tags.prototype = { + /** + * Retrieves all available tags in current domain. + * + * @param {Function} callback + * @param {Error} callback.err + * @param {Object[]} callback.tags Array of object with single `tagname` field. + */ + getAll: function(callback) { + var sql = "SELECT tagname FROM tags WHERE domain = ? ORDER BY tagname"; + this.db.query(sql, [this.domain], function(err, rows) { + if (err) { + callback(err); + return; + } + callback(null, rows.map(function(r) { return {tagname: r.tagname}; })); + }); + }, + /** * Adds tag to the comment. * diff --git a/comments/spec/tags.spec.js b/comments/spec/tags.spec.js index a3ce9f17..17c57cc1 100644 --- a/comments/spec/tags.spec.js +++ b/comments/spec/tags.spec.js @@ -19,6 +19,22 @@ describe("Tags", function() { connection.end(); }); + it("#getAllTags returns all tags in current domain", function(done) { + comments.getAllTags(function(err, tags) { + expect(tags).toEqual([{tagname: "bug"}, {tagname: "feature"}]); + done(); + }); + }); + + it("#getAllTags returns empty array when no tags in current domain", function(done) { + comments = new Comments(new DbFacade(connection), "blabla"); + + comments.getAllTags(function(err, tags) { + expect(tags).toEqual([]); + done(); + }); + }); + it("each comment has concatenated list of tags", function(done) { comments.getById(1, function(err, com) { expect(com.tags).toEqual("bug\tfeature"); diff --git a/template/app/view/comments/TagEditor.js b/template/app/view/comments/TagEditor.js index c65aa53a..ce511437 100644 --- a/template/app/view/comments/TagEditor.js +++ b/template/app/view/comments/TagEditor.js @@ -3,30 +3,48 @@ */ Ext.define("Docs.view.comments.TagEditor", { extend: "Ext.container.Container", + requires: ["Docs.Comments"], floating: true, hidden: true, componentCls: "comments-tageditor", - initComponent: function() { - var tagnames = Ext.create('Ext.data.Store', { - fields: ['name'], - data: [ - {name: "Fixed"}, - {name: "Bug"}, - {name: "Fixed in 4.1"} - ] - }); + statics: { + cachedStore: undefined, + getStore: function() { + if (!this.cachedStore) { + this.cachedStore = Ext.create('Ext.data.Store', { + fields: ['tagname'], + proxy: { + type: "ajax", + url: Docs.Comments.buildRequestUrl("/tags"), + reader: { + type: "json", + root: "tags" + }, + sorters: [{ + property: 'tagname', + direction: 'ASC' + }] + } + }); + this.cachedStore.load(); + } + + return this.cachedStore; + } + }, + initComponent: function() { this.items = [ { xtype: 'combobox', listConfig: { cls: "comments-tageditor-boundlist" }, - store: tagnames, + store: this.statics().getStore(), queryMode: "local", - displayField: "name", - valueField: "name", + displayField: "tagname", + valueField: "tagname", enableKeyEvents: true, listeners: { select: this.handleSelect, @@ -56,15 +74,33 @@ Ext.define("Docs.view.comments.TagEditor", { }, handleSelect: function() { - var value = Ext.String.trim(this.down("combobox").getValue()); + var value = Ext.String.trim(this.down("combobox").getValue() || ""); if (value) { /** * @event select * Fired when a tagname entered to the field and ENTER pressed. * @param {String} tagname */ - this.fireEvent("select", value); + var tagname = this.rememberNewTag(value); + this.fireEvent("select", tagname); } this.destroy(); + }, + + // when tagname doesn't exist in our tags story yet, add it there. + // in either case return the tagname that's going to be added to + // the current comment. + rememberNewTag: function(tagname) { + var store = this.statics().getStore(); + var re = new RegExp("^" + Ext.String.escapeRegex(tagname) + "$", "i"); + var matches = store.query("tagname", re); + if (matches.getCount() === 0) { + store.add({tagname: tagname}); + store.sort(); + return tagname; + } + else { + return matches.get(0).get("tagname"); + } } }); \ No newline at end of file -- GitLab