You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@couchdb.apache.org by robertkowalski <gi...@git.apache.org> on 2014/10/22 16:51:16 UTC

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

GitHub user robertkowalski opened a pull request:

    https://github.com/apache/couchdb-fauxton/pull/106

    Port View Indexes work from PR #33

    This is porting over some of the work done in #33 around indexes with some modifications
    
    Here are the main changes:
    
     - the select-all buttons + bulkdelete are now in the right-header / header / apibar area
     - the documents are styled different
     - indexes got an own module where we can add "lists & freinds" in a later step
     - we got a two-pane layout for creating indexes with a nice couchdb watermark. there is no preview implemented yet, but we can do this in a later step
     - when you open an existing index, you will get a nice view where you can modify the current design doc and then save it as a new index on the left side and you get the current results on the right side

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/robertkowalski/couchdb-fauxton port-views

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/couchdb-fauxton/pull/106.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #106
    
----
commit 309200b5e9b60797f0ef77512f549f449bc88d8d
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-14T14:12:33Z

    import index module

commit ea6abc5fe652909cf697504deba52c2e0a7190fe
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-14T14:29:32Z

    load indexes module

commit 07ef0818a77fe86b19af423c8e7e3abdfa6b77ab
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-14T14:37:50Z

    add couch watermark

commit 6f0f9d66194d052ef226ae6a4b8cf41598721a49
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-14T14:54:27Z

    add window-resizeable-half class

commit 966e1c78e82e66ea46f8e4eb195116b961261a4c
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-15T08:58:33Z

    use <%- instead of <%=

commit 7046ff6445f4e5ad3051991e6049c027df74d03d
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-15T09:04:06Z

    load new view also on click in dropdown

commit 756fc32049490b68ff21fad378177e991b376f14
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-15T12:32:51Z

    resizing two-panes

commit 01fe010dfdb48b1f3429a61a723832ed70326cda
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-15T12:53:56Z

    import template-styles

commit f2d9e79a86fdf0b4a0337b2a4e4eedeaaa9503d6
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-15T16:38:13Z

    delete routes in documents

commit b524eb97dec4f1b5f3aa209add4c03ee47967b4a
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-16T10:58:53Z

    use new queryoptions-tray

commit 3d04def7ddb4af944e74efd8e373c6d52db3ceb9
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-16T12:40:43Z

    use preview screen to give some feedback

commit 594c64af0b12562c74a8eeb5c08adfcced379eba
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-16T13:17:18Z

    remove old viewindex stuff

commit 66d11dd97a872164f6710122d6977a25f7672944
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-16T14:08:55Z

    fix route

commit ae257646be1042b95a68c52d0dbe741e1a51acff
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-16T14:21:37Z

    document style

commit 195759c9eabe28f0d3e53b51ea8d16f454591d12
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-16T14:40:17Z

    style alldocs-items

commit a4824018c837e32f66b43c668b642d7345096425
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-16T14:55:19Z

    deactivate json view - it is not in the current scope

commit 893d9704878a51e4e39fdfec36d5470b555e5fde
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-16T15:19:15Z

    fix padding

commit d6c97fe83d169218978dfa406c86b2b6fe1524b1
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-16T16:00:36Z

    fix design doc metadata padding

commit 6d35e08e7bc03e65cb416cfebc89e04d58b9e99b
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-16T16:03:15Z

    cleanup

commit be2a60960351e6e8255abd7c155539f2d4430794
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-16T19:34:28Z

    force render

commit 2a391852bb73a9cc474a5431275c17c8956ffc26
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-17T12:59:28Z

    remove duplicate 'new view'
    
    we have 'secondary view'

commit 1bbf324851161befece6f4c641cffd1d212f4718
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-21T09:28:52Z

    wip select-all

commit 1ec73cedc979d784babf5d333735042a26827395
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-21T11:26:15Z

    remove query tray in config WIP

commit a2a55c2e33ea167e0bcb3ff8103ef08cd7866b2e
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-21T13:59:01Z

    remove not used parts of the index module

commit 7df0e4a1dfedcc7cda75e4a4681cb92ce0d21d05
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-21T13:50:26Z

    apply style guide

commit 90c9f681bd4a25bac59886b395161c1332f7d55b
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-21T14:14:06Z

    escape template variables
    
    unescaped ones can lead to xss

commit 3c9734c98381f257ca2b1debac698592f5d94973
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-22T10:29:52Z

    remove right header for now
    
    it makes sense once the preview works to include the query-tray

commit 9455eea88b43a529bcca684e0468592e9a9d260b
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-22T10:48:59Z

    make dropdown on view clickable

commit 37295eabb81af7674b15fd8e781d1809923e31fb
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-22T10:59:05Z

    fix pagination footer position

commit 974daa55e6da38233370a50df1eac0fbe5ff0769
Author: Robert Kowalski <ro...@apache.org>
Date:   2014-10-22T11:23:20Z

    remove not working preview

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#issuecomment-60211433
  
    hi @seanbarclay - would be really awesome if you could give us some feedback on this today


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393567
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    +        endpoint: this.endpoint,
    +        documentation: this.documentation
    +      }));
    +
    +      this.advancedOptions = this.insertView('#query-options', new QueryOptions.QueryOptionsTray({
    +        database: this.database,
    +        viewName: this.viewName,
    +        ddocName: this.model.id,
    +        hasReduce: this.hasReduce(),
    +        showStale: true
    +      }));
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('advancedOptions:updateView');
    +    },
    +
    +    hasReduce: function () {
    +
    +    },
    +
    +    updateView: function (event, paramInfo) {
    +       event.preventDefault();
    +
    +       var errorParams = paramInfo.errorParams,
    +           params = paramInfo.params;
    +
    +       if (_.any(errorParams)) {
    +         _.map(errorParams, function (param) {
    +           return FauxtonAPI.addNotification({
    +             msg: 'JSON Parse Error on field: '+param.name,
    +             type: 'error',
    +             clear: true
    +           });
    +         });
    +         FauxtonAPI.addNotification({
    +           msg: 'Make sure that strings are properly quoted and any other values are valid JSON structures',
    +           type: 'warning',
    +           clear: true
    +         });
    +
    +         return false;
    +      }
    +
    +       var fragment = window.location.hash.replace(/\?.*$/, '');
    +       if (!_.isEmpty(params)) {
    +        fragment = fragment + '?' + $.param(params);
    +       }
    +
    +       FauxtonAPI.navigate(fragment, {trigger: false});
    +       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
    +    }
    +  });
    +
    +  Views.PreviewScreen = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/preview_screen',
    +    className: 'watermark-logo',
    +
    +    initialize: function () {
    +      this.listenTo(FauxtonAPI.Events, 'indexes:newView', this.changeText);
    +    },
    +
    +    changeText: function () {
    +      this.$('.js-status').text('Index is building');
    +    }
    +  });
    +
    +
    +  Views.Row = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/index_row_docular',
    +    className: 'doc-row',
    +    events: {
    +      'click button.delete': 'destroy'
    +    },
    +
    +    destroy: function (event) {
    +      event.preventDefault();
    +
    +      window.alert('Cannot delete a document generated from a view.');
    +    },
    +
    +    beforeRender: function () {
    +      var newLinks = [{
    +        links: [{
    +          title: 'JSON',
    +          icon: 'fonticon-json'
    +        }]
    +      }];
    +
    +      this.insertView('.view-doc-menu', new Components.MenuDropDown({
    +        icon: 'fonticon-drop-down-dots',
    +        links: newLinks
    +      }));
    +    },
    +
    +    serialize: function() {
    +      return {
    +        docID: this.model.get('id'),
    +        doc: this.model,
    +        url: this.model.url('app')
    +      };
    +    }
    +  });
    +
    +  Views.IndexCore = FauxtonAPI.View.extend({
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo ? options.ddocInfo.id : '';
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +    },
    +
    +    establish: function () {
    +      if (this.ddocInfo) {
    +        return this.ddocInfo.fetch();
    +      }
    +    },
    +
    +    serialize: function () {
    +      return {
    +        database: this.database.get('id'),
    +        ddocs: this.ddocs,
    +        ddoc: this.model,
    +        ddocName: this.model.id,
    +        viewName: this.viewName,
    +        newView: this.newView,
    +        langTemplates: this.langTemplates.javascript
    +      };
    +    }
    +  });
    +
    +  Views.ViewEditor = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/view_editor',
    +    builtinReduces: ['_sum', '_count', '_stats'],
    +
    +    events: {
    +      'click button.save': 'saveView',
    +      'click button.delete': 'deleteView',
    +      'change select#reduce-function-selector': 'updateReduce',
    +      'click #db-views-tabs-nav': 'toggleIndexNav',
    +      'click .beautify_map':  'beautifyCode',
    +      'click .beautify_reduce':  'beautifyCode'
    +    },
    +
    +    langTemplates: {
    +      'javascript': {
    +        map: 'function(doc) {\n  emit(doc._id, 1);\n}',
    +        reduce: 'function(keys, values, rereduce){\n  if (rereduce){\n    return sum(values);\n  } else {\n    return values.length;\n  }\n}'
    +      }
    +    },
    +
    +    defaultLang: 'javascript',
    +
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo.id;
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +
    +      FauxtonAPI.Events.on('index:delete', this.deleteEvent);
    +    },
    +
    +    establish: function () {
    +      if (!this.ddocInfo) {
    +        return;
    +      }
    +
    +      return this.ddocInfo.fetch();
    +    },
    +
    +    updateValues: function () {
    +      var notification;
    --- End diff --
    
    We don't need to assign `notification`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19225516
  
    --- Diff: app/addons/documents/routes-documents.js ---
    @@ -316,41 +232,26 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou
           };
         },
     
    -    createViewDocumentsView: function (options) {
    -      return this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
    -        database: options.database,
    -        collection: options.indexedDocs,
    -        nestedView: Documents.Views.Row,
    -        viewList: true,
    -        ddocInfo: this.ddocInfo(options.designDoc, options.designDocs, options.view),
    -        docParams: options.docParams,
    -        params: options.urlParams
    -      }));
    +    toggleSelectheader: function(){
    --- End diff --
    
    Super minor. function - space - ().


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19228974
  
    --- Diff: app/addons/documents/views.js ---
    @@ -176,11 +217,38 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions)
     
       Views.Document = FauxtonAPI.View.extend({
         template: "addons/documents/templates/all_docs_item",
    -    tagName: "tr",
    -    className: "all-docs-item",
    +
    +    className: function () {
    +      return (this.showSelect ? "showSelect" : "") + " all-docs-item doc-row";
    +    },
     
         initialize: function (options) {
           this.checked = options.checked;
    +      this.expanded = options.expanded;
    +      this.showSelect = false;
    +      _.bindAll(this);
    +
    +      FauxtonAPI.Events.on("documents:showSelectAll", this.showSelectBox);
    +      FauxtonAPI.Events.on("documents:collapse", this.collapse);
    +      FauxtonAPI.Events.on("documents:selectAll", this.selectAll);
    +    },
    --- End diff --
    
    More single quotes.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19228953
  
    --- Diff: app/addons/documents/views.js ---
    @@ -176,11 +217,38 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions)
     
       Views.Document = FauxtonAPI.View.extend({
         template: "addons/documents/templates/all_docs_item",
    -    tagName: "tr",
    -    className: "all-docs-item",
    +
    +    className: function () {
    +      return (this.showSelect ? "showSelect" : "") + " all-docs-item doc-row";
    --- End diff --
    
    Single quotes.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: [WIP] Port View Indexes work from PR...

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#issuecomment-61301004
  
    please take a look @seanbarclay :)


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19228421
  
    --- Diff: app/addons/documents/templates/all_docs_list.html ---
    @@ -10,38 +10,21 @@
     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="view">
    -  <% if (!viewList) { %>
    -    <div class="row">
    -      <div class="btn-toolbar span6">
    -        <button type="button" class="btn btn-small all" data-toggle="button">✓ All</button>
    -        <button class="btn btn-small disabled js-bulk-delete"><i class="icon-trash"></i></button>
    -        <% if (expandDocs) { %>
    -        <button id="collapse" class="btn btn-small"><i class="icon-minus"></i> Collapse</button>
    -        <% } else { %>
    -        <button id="collapse" class="btn btn-small"><i class="icon-plus"></i> Expand</button>
    -        <% } %>
    -      </div>
    -    </div>
    -  <% } %>
    -  <p>
     
    -  <table class="all-docs table table-striped table-condensed">
    -    <tbody></tbody>
    -  </table>
    +  <div id="doc-list"></div>
     
       <% if (endOfResults) { %>
    -  <div class="end-of-results text-center well">
    --- End diff --
    
    Just want to confirm this file was merged correctly. I added the .end-of-results class to fix a small formatting issue with this section (too much padding on the bottom).


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19229350
  
    --- Diff: app/addons/indexes/resources.js ---
    @@ -0,0 +1,217 @@
    +// 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.
    +define([
    +  'app',
    +  'api',
    +  'cloudant.pagingcollection'
    +],
    +
    +function (app, FauxtonAPI, PagingCollection) {
    +  var Resources = {};
    +
    +  Resources.QueryParams = (function () {
    +    var _eachParams = function (params, action) {
    +      // clone to avoid in-place modification
    +      var result = _.clone(params);
    +
    +      _.each(['startkey', 'endkey', 'key'], function (key) {
    +        if (_.has(result, key)) {
    +          result[key] = action(result[key]);
    +        }
    +      });
    +
    +      return result;
    +    };
    +
    +    return {
    +      parse: function (params) {
    +        return _eachParams(params, JSON.parse);
    +      },
    +
    +      stringify: function (params) {
    +        return _eachParams(params, JSON.stringify);
    +      }
    +    };
    +  })();
    +
    +  Resources.ViewRow = FauxtonAPI.Model.extend({
    +    // this is a hack so that backbone.collections doesn't group
    +    // these by id and reduce the number of items returned.
    +    idAttribute: '_id',
    +
    +    docType: function () {
    +      if (!this.id) return 'reduction';
    --- End diff --
    
    { and }


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393545
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    +        endpoint: this.endpoint,
    +        documentation: this.documentation
    +      }));
    +
    +      this.advancedOptions = this.insertView('#query-options', new QueryOptions.QueryOptionsTray({
    +        database: this.database,
    +        viewName: this.viewName,
    +        ddocName: this.model.id,
    +        hasReduce: this.hasReduce(),
    +        showStale: true
    +      }));
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('advancedOptions:updateView');
    +    },
    +
    +    hasReduce: function () {
    +
    +    },
    +
    +    updateView: function (event, paramInfo) {
    +       event.preventDefault();
    +
    +       var errorParams = paramInfo.errorParams,
    +           params = paramInfo.params;
    +
    +       if (_.any(errorParams)) {
    +         _.map(errorParams, function (param) {
    +           return FauxtonAPI.addNotification({
    +             msg: 'JSON Parse Error on field: '+param.name,
    +             type: 'error',
    +             clear: true
    +           });
    +         });
    +         FauxtonAPI.addNotification({
    +           msg: 'Make sure that strings are properly quoted and any other values are valid JSON structures',
    +           type: 'warning',
    +           clear: true
    +         });
    +
    +         return false;
    +      }
    +
    +       var fragment = window.location.hash.replace(/\?.*$/, '');
    +       if (!_.isEmpty(params)) {
    +        fragment = fragment + '?' + $.param(params);
    +       }
    +
    +       FauxtonAPI.navigate(fragment, {trigger: false});
    +       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
    +    }
    +  });
    +
    +  Views.PreviewScreen = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/preview_screen',
    +    className: 'watermark-logo',
    +
    +    initialize: function () {
    +      this.listenTo(FauxtonAPI.Events, 'indexes:newView', this.changeText);
    +    },
    +
    +    changeText: function () {
    +      this.$('.js-status').text('Index is building');
    +    }
    +  });
    +
    +
    +  Views.Row = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/index_row_docular',
    +    className: 'doc-row',
    +    events: {
    +      'click button.delete': 'destroy'
    +    },
    +
    +    destroy: function (event) {
    +      event.preventDefault();
    +
    +      window.alert('Cannot delete a document generated from a view.');
    +    },
    +
    +    beforeRender: function () {
    +      var newLinks = [{
    +        links: [{
    +          title: 'JSON',
    +          icon: 'fonticon-json'
    +        }]
    +      }];
    +
    +      this.insertView('.view-doc-menu', new Components.MenuDropDown({
    +        icon: 'fonticon-drop-down-dots',
    +        links: newLinks
    +      }));
    +    },
    +
    +    serialize: function() {
    +      return {
    +        docID: this.model.get('id'),
    +        doc: this.model,
    +        url: this.model.url('app')
    +      };
    +    }
    +  });
    +
    +  Views.IndexCore = FauxtonAPI.View.extend({
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo ? options.ddocInfo.id : '';
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +    },
    +
    +    establish: function () {
    +      if (this.ddocInfo) {
    +        return this.ddocInfo.fetch();
    +      }
    +    },
    +
    +    serialize: function () {
    +      return {
    +        database: this.database.get('id'),
    +        ddocs: this.ddocs,
    +        ddoc: this.model,
    +        ddocName: this.model.id,
    +        viewName: this.viewName,
    +        newView: this.newView,
    +        langTemplates: this.langTemplates.javascript
    +      };
    +    }
    +  });
    +
    +  Views.ViewEditor = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/view_editor',
    +    builtinReduces: ['_sum', '_count', '_stats'],
    +
    +    events: {
    +      'click button.save': 'saveView',
    +      'click button.delete': 'deleteView',
    +      'change select#reduce-function-selector': 'updateReduce',
    +      'click #db-views-tabs-nav': 'toggleIndexNav',
    +      'click .beautify_map':  'beautifyCode',
    +      'click .beautify_reduce':  'beautifyCode'
    +    },
    +
    +    langTemplates: {
    +      'javascript': {
    +        map: 'function(doc) {\n  emit(doc._id, 1);\n}',
    +        reduce: 'function(keys, values, rereduce){\n  if (rereduce){\n    return sum(values);\n  } else {\n    return values.length;\n  }\n}'
    +      }
    +    },
    +
    +    defaultLang: 'javascript',
    +
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo.id;
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +
    +      FauxtonAPI.Events.on('index:delete', this.deleteEvent);
    --- End diff --
    
    Rather use `this.listenTo`.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393594
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    +        endpoint: this.endpoint,
    +        documentation: this.documentation
    +      }));
    +
    +      this.advancedOptions = this.insertView('#query-options', new QueryOptions.QueryOptionsTray({
    +        database: this.database,
    +        viewName: this.viewName,
    +        ddocName: this.model.id,
    +        hasReduce: this.hasReduce(),
    +        showStale: true
    +      }));
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('advancedOptions:updateView');
    +    },
    +
    +    hasReduce: function () {
    +
    +    },
    +
    +    updateView: function (event, paramInfo) {
    +       event.preventDefault();
    +
    +       var errorParams = paramInfo.errorParams,
    +           params = paramInfo.params;
    +
    +       if (_.any(errorParams)) {
    +         _.map(errorParams, function (param) {
    +           return FauxtonAPI.addNotification({
    +             msg: 'JSON Parse Error on field: '+param.name,
    +             type: 'error',
    +             clear: true
    +           });
    +         });
    +         FauxtonAPI.addNotification({
    +           msg: 'Make sure that strings are properly quoted and any other values are valid JSON structures',
    +           type: 'warning',
    +           clear: true
    +         });
    +
    +         return false;
    +      }
    +
    +       var fragment = window.location.hash.replace(/\?.*$/, '');
    +       if (!_.isEmpty(params)) {
    +        fragment = fragment + '?' + $.param(params);
    +       }
    +
    +       FauxtonAPI.navigate(fragment, {trigger: false});
    +       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
    +    }
    +  });
    +
    +  Views.PreviewScreen = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/preview_screen',
    +    className: 'watermark-logo',
    +
    +    initialize: function () {
    +      this.listenTo(FauxtonAPI.Events, 'indexes:newView', this.changeText);
    +    },
    +
    +    changeText: function () {
    +      this.$('.js-status').text('Index is building');
    +    }
    +  });
    +
    +
    +  Views.Row = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/index_row_docular',
    +    className: 'doc-row',
    +    events: {
    +      'click button.delete': 'destroy'
    +    },
    +
    +    destroy: function (event) {
    +      event.preventDefault();
    +
    +      window.alert('Cannot delete a document generated from a view.');
    +    },
    +
    +    beforeRender: function () {
    +      var newLinks = [{
    +        links: [{
    +          title: 'JSON',
    +          icon: 'fonticon-json'
    +        }]
    +      }];
    +
    +      this.insertView('.view-doc-menu', new Components.MenuDropDown({
    +        icon: 'fonticon-drop-down-dots',
    +        links: newLinks
    +      }));
    +    },
    +
    +    serialize: function() {
    +      return {
    +        docID: this.model.get('id'),
    +        doc: this.model,
    +        url: this.model.url('app')
    +      };
    +    }
    +  });
    +
    +  Views.IndexCore = FauxtonAPI.View.extend({
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo ? options.ddocInfo.id : '';
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +    },
    +
    +    establish: function () {
    +      if (this.ddocInfo) {
    +        return this.ddocInfo.fetch();
    +      }
    +    },
    +
    +    serialize: function () {
    +      return {
    +        database: this.database.get('id'),
    +        ddocs: this.ddocs,
    +        ddoc: this.model,
    +        ddocName: this.model.id,
    +        viewName: this.viewName,
    +        newView: this.newView,
    +        langTemplates: this.langTemplates.javascript
    +      };
    +    }
    +  });
    +
    +  Views.ViewEditor = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/view_editor',
    +    builtinReduces: ['_sum', '_count', '_stats'],
    +
    +    events: {
    +      'click button.save': 'saveView',
    +      'click button.delete': 'deleteView',
    +      'change select#reduce-function-selector': 'updateReduce',
    +      'click #db-views-tabs-nav': 'toggleIndexNav',
    +      'click .beautify_map':  'beautifyCode',
    +      'click .beautify_reduce':  'beautifyCode'
    +    },
    +
    +    langTemplates: {
    +      'javascript': {
    +        map: 'function(doc) {\n  emit(doc._id, 1);\n}',
    +        reduce: 'function(keys, values, rereduce){\n  if (rereduce){\n    return sum(values);\n  } else {\n    return values.length;\n  }\n}'
    +      }
    +    },
    +
    +    defaultLang: 'javascript',
    +
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo.id;
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +
    +      FauxtonAPI.Events.on('index:delete', this.deleteEvent);
    +    },
    +
    +    establish: function () {
    +      if (!this.ddocInfo) {
    +        return;
    +      }
    +
    +      return this.ddocInfo.fetch();
    +    },
    +
    +    updateValues: function () {
    +      var notification;
    +      if (this.model.changedAttributes()) {
    +        notification = FauxtonAPI.addNotification({
    +          msg: 'Document saved successfully.',
    +          type: 'success',
    +          clear: true
    +        });
    +        this.editor.setValue(this.model.prettyJSON());
    +      }
    +    },
    +
    +    updateReduce: function (event) {
    +      var $ele = $('#reduce-function-selector');
    +      var $reduceContainer = $('.control-group.reduce-function');
    +      if ($ele.val() == 'CUSTOM') {
    +        this.createReduceEditor();
    +        this.reduceEditor.setValue(this.langTemplates.javascript.reduce);
    +        $reduceContainer.show();
    +      } else {
    +        $reduceContainer.hide();
    +      }
    +    },
    +
    +    deleteEvent: function(){
    +      this.deleteView();
    +    },
    +
    +    deleteView: function (event) {
    +      event && event.preventDefault();
    +
    +      if (this.newView) { return alert('Cannot delete a new view.'); }
    +      if (!confirm('Are you sure you want to delete this view?')) { return; }
    +
    +      var that = this,
    --- End diff --
    
    We don't need `that = this` assignment.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by seanbarclay <gi...@git.apache.org>.
Github user seanbarclay commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#issuecomment-62844574
  
    @robertkowalski Apologies in advance: https://docs.google.com/a/cloudant.com/document/d/1CkVbPXJ2x3-octk9uFktXgV284QxhdsQ5ucSWkRKSM8/edit?usp=sharing
    
    Let me know if you would like to walk through this together so that we're both on the same page. 
    Thanks



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393441
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    +        endpoint: this.endpoint,
    +        documentation: this.documentation
    +      }));
    +
    +      this.advancedOptions = this.insertView('#query-options', new QueryOptions.QueryOptionsTray({
    +        database: this.database,
    +        viewName: this.viewName,
    +        ddocName: this.model.id,
    +        hasReduce: this.hasReduce(),
    +        showStale: true
    +      }));
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('advancedOptions:updateView');
    +    },
    +
    +    hasReduce: function () {
    --- End diff --
    
    Do we need this function?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393464
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    --- End diff --
    
    We don't need the api bar in the right header any more. We worked to move this out.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#issuecomment-60123897
  
    Looks great, @robertkowalski! Just a few nit-picky things.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393491
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    --- End diff --
    
    If you you `this.listenTo` you don't need the `cleanup` method.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393478
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    --- End diff --
    
    I'm not a big fan of `_.bindAll`. I don't see any functions in this view that need it.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393549
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    +        endpoint: this.endpoint,
    +        documentation: this.documentation
    +      }));
    +
    +      this.advancedOptions = this.insertView('#query-options', new QueryOptions.QueryOptionsTray({
    +        database: this.database,
    +        viewName: this.viewName,
    +        ddocName: this.model.id,
    +        hasReduce: this.hasReduce(),
    +        showStale: true
    +      }));
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('advancedOptions:updateView');
    +    },
    +
    +    hasReduce: function () {
    +
    +    },
    +
    +    updateView: function (event, paramInfo) {
    +       event.preventDefault();
    +
    +       var errorParams = paramInfo.errorParams,
    +           params = paramInfo.params;
    +
    +       if (_.any(errorParams)) {
    +         _.map(errorParams, function (param) {
    +           return FauxtonAPI.addNotification({
    +             msg: 'JSON Parse Error on field: '+param.name,
    +             type: 'error',
    +             clear: true
    +           });
    +         });
    +         FauxtonAPI.addNotification({
    +           msg: 'Make sure that strings are properly quoted and any other values are valid JSON structures',
    +           type: 'warning',
    +           clear: true
    +         });
    +
    +         return false;
    +      }
    +
    +       var fragment = window.location.hash.replace(/\?.*$/, '');
    +       if (!_.isEmpty(params)) {
    +        fragment = fragment + '?' + $.param(params);
    +       }
    +
    +       FauxtonAPI.navigate(fragment, {trigger: false});
    +       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
    +    }
    +  });
    +
    +  Views.PreviewScreen = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/preview_screen',
    +    className: 'watermark-logo',
    +
    +    initialize: function () {
    +      this.listenTo(FauxtonAPI.Events, 'indexes:newView', this.changeText);
    +    },
    +
    +    changeText: function () {
    +      this.$('.js-status').text('Index is building');
    +    }
    +  });
    +
    +
    +  Views.Row = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/index_row_docular',
    +    className: 'doc-row',
    +    events: {
    +      'click button.delete': 'destroy'
    +    },
    +
    +    destroy: function (event) {
    +      event.preventDefault();
    +
    +      window.alert('Cannot delete a document generated from a view.');
    +    },
    +
    +    beforeRender: function () {
    +      var newLinks = [{
    +        links: [{
    +          title: 'JSON',
    +          icon: 'fonticon-json'
    +        }]
    +      }];
    +
    +      this.insertView('.view-doc-menu', new Components.MenuDropDown({
    +        icon: 'fonticon-drop-down-dots',
    +        links: newLinks
    +      }));
    +    },
    +
    +    serialize: function() {
    +      return {
    +        docID: this.model.get('id'),
    +        doc: this.model,
    +        url: this.model.url('app')
    +      };
    +    }
    +  });
    +
    +  Views.IndexCore = FauxtonAPI.View.extend({
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo ? options.ddocInfo.id : '';
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +    },
    +
    +    establish: function () {
    +      if (this.ddocInfo) {
    +        return this.ddocInfo.fetch();
    +      }
    +    },
    +
    +    serialize: function () {
    +      return {
    +        database: this.database.get('id'),
    +        ddocs: this.ddocs,
    +        ddoc: this.model,
    +        ddocName: this.model.id,
    +        viewName: this.viewName,
    +        newView: this.newView,
    +        langTemplates: this.langTemplates.javascript
    +      };
    +    }
    +  });
    +
    +  Views.ViewEditor = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/view_editor',
    +    builtinReduces: ['_sum', '_count', '_stats'],
    +
    +    events: {
    +      'click button.save': 'saveView',
    +      'click button.delete': 'deleteView',
    +      'change select#reduce-function-selector': 'updateReduce',
    +      'click #db-views-tabs-nav': 'toggleIndexNav',
    +      'click .beautify_map':  'beautifyCode',
    +      'click .beautify_reduce':  'beautifyCode'
    +    },
    +
    +    langTemplates: {
    +      'javascript': {
    +        map: 'function(doc) {\n  emit(doc._id, 1);\n}',
    +        reduce: 'function(keys, values, rereduce){\n  if (rereduce){\n    return sum(values);\n  } else {\n    return values.length;\n  }\n}'
    +      }
    +    },
    +
    +    defaultLang: 'javascript',
    +
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo.id;
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    --- End diff --
    
    Can we remove this.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19266094
  
    --- Diff: app/addons/documents/templates/all_docs_list.html ---
    @@ -10,38 +10,21 @@
     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="view">
    -  <% if (!viewList) { %>
    -    <div class="row">
    -      <div class="btn-toolbar span6">
    -        <button type="button" class="btn btn-small all" data-toggle="button">✓ All</button>
    -        <button class="btn btn-small disabled js-bulk-delete"><i class="icon-trash"></i></button>
    -        <% if (expandDocs) { %>
    -        <button id="collapse" class="btn btn-small"><i class="icon-minus"></i> Collapse</button>
    -        <% } else { %>
    -        <button id="collapse" class="btn btn-small"><i class="icon-plus"></i> Expand</button>
    -        <% } %>
    -      </div>
    -    </div>
    -  <% } %>
    -  <p>
     
    -  <table class="all-docs table table-striped table-condensed">
    -    <tbody></tbody>
    -  </table>
    +  <div id="doc-list"></div>
     
       <% if (endOfResults) { %>
    -  <div class="end-of-results text-center well">
    --- End diff --
    
    thanks, corrected


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19228491
  
    --- Diff: app/addons/documents/templates/all_docs_list.html ---
    @@ -10,38 +10,21 @@
     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="view">
    -  <% if (!viewList) { %>
    -    <div class="row">
    -      <div class="btn-toolbar span6">
    -        <button type="button" class="btn btn-small all" data-toggle="button">✓ All</button>
    -        <button class="btn btn-small disabled js-bulk-delete"><i class="icon-trash"></i></button>
    -        <% if (expandDocs) { %>
    -        <button id="collapse" class="btn btn-small"><i class="icon-minus"></i> Collapse</button>
    -        <% } else { %>
    -        <button id="collapse" class="btn btn-small"><i class="icon-plus"></i> Expand</button>
    -        <% } %>
    -      </div>
    -    </div>
    -  <% } %>
    -  <p>
     
    -  <table class="all-docs table table-striped table-condensed">
    -    <tbody></tbody>
    -  </table>
    +  <div id="doc-list"></div>
     
       <% if (endOfResults) { %>
    -  <div class="end-of-results text-center well">
    +  <div class="text-center well">
         <p class="muted">
    -      End of results - <a id="js-end-results" href="#query" data-bypass="true">edit query</a>
    +      End of results - <a id="js-end-results" href="#query" data-bypass="true" data-toggle="tab">edit query</a>
    --- End diff --
    
    Again, just want to confirm this is correct. I remove the bootstrap-specific data-toggle attribute because it no longer toggles a tab, but shows the query options tray via a JS click event.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393525
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    +        endpoint: this.endpoint,
    +        documentation: this.documentation
    +      }));
    +
    +      this.advancedOptions = this.insertView('#query-options', new QueryOptions.QueryOptionsTray({
    +        database: this.database,
    +        viewName: this.viewName,
    +        ddocName: this.model.id,
    +        hasReduce: this.hasReduce(),
    +        showStale: true
    +      }));
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('advancedOptions:updateView');
    +    },
    +
    +    hasReduce: function () {
    +
    +    },
    +
    +    updateView: function (event, paramInfo) {
    +       event.preventDefault();
    +
    +       var errorParams = paramInfo.errorParams,
    +           params = paramInfo.params;
    +
    +       if (_.any(errorParams)) {
    +         _.map(errorParams, function (param) {
    +           return FauxtonAPI.addNotification({
    +             msg: 'JSON Parse Error on field: '+param.name,
    +             type: 'error',
    +             clear: true
    +           });
    +         });
    +         FauxtonAPI.addNotification({
    +           msg: 'Make sure that strings are properly quoted and any other values are valid JSON structures',
    +           type: 'warning',
    +           clear: true
    +         });
    +
    +         return false;
    +      }
    +
    +       var fragment = window.location.hash.replace(/\?.*$/, '');
    +       if (!_.isEmpty(params)) {
    +        fragment = fragment + '?' + $.param(params);
    +       }
    +
    +       FauxtonAPI.navigate(fragment, {trigger: false});
    +       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
    +    }
    +  });
    +
    +  Views.PreviewScreen = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/preview_screen',
    +    className: 'watermark-logo',
    +
    +    initialize: function () {
    +      this.listenTo(FauxtonAPI.Events, 'indexes:newView', this.changeText);
    +    },
    +
    +    changeText: function () {
    +      this.$('.js-status').text('Index is building');
    +    }
    +  });
    +
    +
    +  Views.Row = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/index_row_docular',
    +    className: 'doc-row',
    +    events: {
    +      'click button.delete': 'destroy'
    +    },
    +
    +    destroy: function (event) {
    +      event.preventDefault();
    +
    +      window.alert('Cannot delete a document generated from a view.');
    +    },
    +
    +    beforeRender: function () {
    +      var newLinks = [{
    +        links: [{
    +          title: 'JSON',
    +          icon: 'fonticon-json'
    +        }]
    +      }];
    +
    +      this.insertView('.view-doc-menu', new Components.MenuDropDown({
    +        icon: 'fonticon-drop-down-dots',
    +        links: newLinks
    +      }));
    +    },
    +
    +    serialize: function() {
    +      return {
    +        docID: this.model.get('id'),
    +        doc: this.model,
    +        url: this.model.url('app')
    +      };
    +    }
    +  });
    +
    +  Views.IndexCore = FauxtonAPI.View.extend({
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo ? options.ddocInfo.id : '';
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    --- End diff --
    
    Can we get rid of this `_bindAll`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19229411
  
    --- Diff: app/addons/indexes/resources.js ---
    @@ -0,0 +1,217 @@
    +// 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.
    +define([
    +  'app',
    +  'api',
    +  'cloudant.pagingcollection'
    +],
    +
    +function (app, FauxtonAPI, PagingCollection) {
    +  var Resources = {};
    +
    +  Resources.QueryParams = (function () {
    +    var _eachParams = function (params, action) {
    +      // clone to avoid in-place modification
    +      var result = _.clone(params);
    +
    +      _.each(['startkey', 'endkey', 'key'], function (key) {
    +        if (_.has(result, key)) {
    +          result[key] = action(result[key]);
    +        }
    +      });
    +
    +      return result;
    +    };
    +
    +    return {
    +      parse: function (params) {
    +        return _eachParams(params, JSON.parse);
    +      },
    +
    +      stringify: function (params) {
    +        return _eachParams(params, JSON.stringify);
    +      }
    +    };
    +  })();
    +
    +  Resources.ViewRow = FauxtonAPI.Model.extend({
    +    // this is a hack so that backbone.collections doesn't group
    +    // these by id and reduce the number of items returned.
    +    idAttribute: '_id',
    +
    +    docType: function () {
    +      if (!this.id) return 'reduction';
    +
    +      return this.id.match(/^_design/) ? 'design doc' : 'doc';
    +    },
    +
    +    documentation: function () {
    +      return 'docs';
    +    },
    +
    +    url: function (context) {
    +      return this.collection.database.url(context) + '/' + this.safeID();
    +    },
    +
    +    isEditable: function () {
    +      return this.docType() != 'reduction';
    --- End diff --
    
    Did we settle on using only === and !===, or their evil twins (==, !=) are okay?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393371
  
    --- Diff: app/addons/fauxton/tests/paginateSpec.js ---
    @@ -59,7 +59,7 @@ define([
             //do this so it doesn't throw an error on other unwired up components
             FauxtonAPI.triggerRouteEvent = function () {};
             //FauxtonAPI.triggerRouteEvent.restore && FauxtonAPI.triggerRouteEvent.restore();
    -        //FauxtonAPI.navigate.restore && FauxtonAPI.navigate.restore(); 
    +        //FauxtonAPI.navigate.restore && FauxtonAPI.navigate.restore();
    --- End diff --
    
    do we need this?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19266031
  
    --- Diff: app/addons/indexes/resources.js ---
    @@ -0,0 +1,217 @@
    +// 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.
    +define([
    +  'app',
    +  'api',
    +  'cloudant.pagingcollection'
    +],
    +
    +function (app, FauxtonAPI, PagingCollection) {
    +  var Resources = {};
    +
    +  Resources.QueryParams = (function () {
    +    var _eachParams = function (params, action) {
    +      // clone to avoid in-place modification
    +      var result = _.clone(params);
    +
    +      _.each(['startkey', 'endkey', 'key'], function (key) {
    +        if (_.has(result, key)) {
    +          result[key] = action(result[key]);
    +        }
    +      });
    +
    +      return result;
    +    };
    +
    +    return {
    +      parse: function (params) {
    +        return _eachParams(params, JSON.parse);
    +      },
    +
    +      stringify: function (params) {
    +        return _eachParams(params, JSON.stringify);
    +      }
    +    };
    +  })();
    +
    +  Resources.ViewRow = FauxtonAPI.Model.extend({
    +    // this is a hack so that backbone.collections doesn't group
    +    // these by id and reduce the number of items returned.
    +    idAttribute: '_id',
    +
    +    docType: function () {
    +      if (!this.id) return 'reduction';
    +
    +      return this.id.match(/^_design/) ? 'design doc' : 'doc';
    +    },
    +
    +    documentation: function () {
    +      return 'docs';
    +    },
    +
    +    url: function (context) {
    +      return this.collection.database.url(context) + '/' + this.safeID();
    +    },
    +
    +    isEditable: function () {
    +      return this.docType() != 'reduction';
    --- End diff --
    
    I prefer `!==`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19228902
  
    --- Diff: app/addons/documents/views.js ---
    @@ -119,6 +119,47 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions)
         }
       });
     
    +  Views.SelectMenuHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/documents/templates/select_doc_menu',
    +    events: {
    +      'click button.all': 'selectAll',
    +      'click button.js-bulk-delete': 'bulkDelete',
    +      'click #collapse': 'collapse',
    +      'click .js-toggle-select-menu': 'selectAllMenu'
    +    },
    +
    +    initialize: function () {
    +      this.listenTo(FauxtonAPI.Events, 'documents:toggleTrashButton', this.toggleTrashButton);
    +    },
    +
    +    toggleTrashButton: function (enabled) {
    +      var $bulkdDeleteButton = this.$('.js-bulk-delete');
    --- End diff --
    
    Typo. $bulkDeleteButton, not $bulkdDeleteButton (sorry, I know this is old code).


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski closed the pull request at:

    https://github.com/apache/couchdb-fauxton/pull/106


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393660
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    +        endpoint: this.endpoint,
    +        documentation: this.documentation
    +      }));
    +
    +      this.advancedOptions = this.insertView('#query-options', new QueryOptions.QueryOptionsTray({
    +        database: this.database,
    +        viewName: this.viewName,
    +        ddocName: this.model.id,
    +        hasReduce: this.hasReduce(),
    +        showStale: true
    +      }));
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('advancedOptions:updateView');
    +    },
    +
    +    hasReduce: function () {
    +
    +    },
    +
    +    updateView: function (event, paramInfo) {
    +       event.preventDefault();
    +
    +       var errorParams = paramInfo.errorParams,
    +           params = paramInfo.params;
    +
    +       if (_.any(errorParams)) {
    +         _.map(errorParams, function (param) {
    +           return FauxtonAPI.addNotification({
    +             msg: 'JSON Parse Error on field: '+param.name,
    +             type: 'error',
    +             clear: true
    +           });
    +         });
    +         FauxtonAPI.addNotification({
    +           msg: 'Make sure that strings are properly quoted and any other values are valid JSON structures',
    +           type: 'warning',
    +           clear: true
    +         });
    +
    +         return false;
    +      }
    +
    +       var fragment = window.location.hash.replace(/\?.*$/, '');
    +       if (!_.isEmpty(params)) {
    +        fragment = fragment + '?' + $.param(params);
    +       }
    +
    +       FauxtonAPI.navigate(fragment, {trigger: false});
    +       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
    +    }
    +  });
    +
    +  Views.PreviewScreen = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/preview_screen',
    +    className: 'watermark-logo',
    +
    +    initialize: function () {
    +      this.listenTo(FauxtonAPI.Events, 'indexes:newView', this.changeText);
    +    },
    +
    +    changeText: function () {
    +      this.$('.js-status').text('Index is building');
    +    }
    +  });
    +
    +
    +  Views.Row = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/index_row_docular',
    +    className: 'doc-row',
    +    events: {
    +      'click button.delete': 'destroy'
    +    },
    +
    +    destroy: function (event) {
    +      event.preventDefault();
    +
    +      window.alert('Cannot delete a document generated from a view.');
    +    },
    +
    +    beforeRender: function () {
    +      var newLinks = [{
    +        links: [{
    +          title: 'JSON',
    +          icon: 'fonticon-json'
    +        }]
    +      }];
    +
    +      this.insertView('.view-doc-menu', new Components.MenuDropDown({
    +        icon: 'fonticon-drop-down-dots',
    +        links: newLinks
    +      }));
    +    },
    +
    +    serialize: function() {
    +      return {
    +        docID: this.model.get('id'),
    +        doc: this.model,
    +        url: this.model.url('app')
    +      };
    +    }
    +  });
    +
    +  Views.IndexCore = FauxtonAPI.View.extend({
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo ? options.ddocInfo.id : '';
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +    },
    +
    +    establish: function () {
    +      if (this.ddocInfo) {
    +        return this.ddocInfo.fetch();
    +      }
    +    },
    +
    +    serialize: function () {
    +      return {
    +        database: this.database.get('id'),
    +        ddocs: this.ddocs,
    +        ddoc: this.model,
    +        ddocName: this.model.id,
    +        viewName: this.viewName,
    +        newView: this.newView,
    +        langTemplates: this.langTemplates.javascript
    +      };
    +    }
    +  });
    +
    +  Views.ViewEditor = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/view_editor',
    +    builtinReduces: ['_sum', '_count', '_stats'],
    +
    +    events: {
    +      'click button.save': 'saveView',
    +      'click button.delete': 'deleteView',
    +      'change select#reduce-function-selector': 'updateReduce',
    +      'click #db-views-tabs-nav': 'toggleIndexNav',
    +      'click .beautify_map':  'beautifyCode',
    +      'click .beautify_reduce':  'beautifyCode'
    +    },
    +
    +    langTemplates: {
    +      'javascript': {
    +        map: 'function(doc) {\n  emit(doc._id, 1);\n}',
    +        reduce: 'function(keys, values, rereduce){\n  if (rereduce){\n    return sum(values);\n  } else {\n    return values.length;\n  }\n}'
    +      }
    +    },
    +
    +    defaultLang: 'javascript',
    +
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo.id;
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +
    +      FauxtonAPI.Events.on('index:delete', this.deleteEvent);
    +    },
    +
    +    establish: function () {
    +      if (!this.ddocInfo) {
    +        return;
    +      }
    +
    +      return this.ddocInfo.fetch();
    +    },
    +
    +    updateValues: function () {
    +      var notification;
    +      if (this.model.changedAttributes()) {
    +        notification = FauxtonAPI.addNotification({
    +          msg: 'Document saved successfully.',
    +          type: 'success',
    +          clear: true
    +        });
    +        this.editor.setValue(this.model.prettyJSON());
    +      }
    +    },
    +
    +    updateReduce: function (event) {
    +      var $ele = $('#reduce-function-selector');
    +      var $reduceContainer = $('.control-group.reduce-function');
    +      if ($ele.val() == 'CUSTOM') {
    +        this.createReduceEditor();
    +        this.reduceEditor.setValue(this.langTemplates.javascript.reduce);
    +        $reduceContainer.show();
    +      } else {
    +        $reduceContainer.hide();
    +      }
    +    },
    +
    +    deleteEvent: function(){
    +      this.deleteView();
    +    },
    +
    +    deleteView: function (event) {
    +      event && event.preventDefault();
    +
    +      if (this.newView) { return alert('Cannot delete a new view.'); }
    +      if (!confirm('Are you sure you want to delete this view?')) { return; }
    +
    +      var that = this,
    +          promise,
    +          viewName = this.$('#index-name').val(),
    +          ddocName = this.$('#ddoc :selected').val(),
    +          ddoc = this.getCurrentDesignDoc();
    +
    +      ddoc.removeDdocView(viewName);
    +
    +      if (ddoc.hasViews()) {
    +        promise = ddoc.save();
    +      } else {
    +        promise = ddoc.destroy();
    +      }
    +
    +      promise.then(function () {
    +        FauxtonAPI.navigate('/database/' + that.database.safeID() + '/_all_docs?limit=' + Databases.DocLimit);
    +        FauxtonAPI.triggerRouteEvent('reloadDesignDocs');
    +      });
    +    },
    +
    +    saveView: function (event) {
    +      var that = this,
    --- End diff --
    
    If possible, could you remove the use of `that` in this method.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19229899
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    +        endpoint: this.endpoint,
    +        documentation: this.documentation
    +      }));
    +
    +      this.advancedOptions = this.insertView('#query-options', new QueryOptions.QueryOptionsTray({
    +        database: this.database,
    +        viewName: this.viewName,
    +        ddocName: this.model.id,
    +        hasReduce: this.hasReduce(),
    +        showStale: true
    +      }));
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('advancedOptions:updateView');
    +    },
    +
    +    hasReduce: function () {
    +
    +    },
    +
    +    updateView: function (event, paramInfo) {
    +       event.preventDefault();
    +
    +       var errorParams = paramInfo.errorParams,
    +           params = paramInfo.params;
    +
    +       if (_.any(errorParams)) {
    +         _.map(errorParams, function (param) {
    +           return FauxtonAPI.addNotification({
    +             msg: 'JSON Parse Error on field: '+param.name,
    +             type: 'error',
    +             clear: true
    +           });
    +         });
    +         FauxtonAPI.addNotification({
    +           msg: 'Make sure that strings are properly quoted and any other values are valid JSON structures',
    +           type: 'warning',
    +           clear: true
    +         });
    +
    +         return false;
    +      }
    +
    +       var fragment = window.location.hash.replace(/\?.*$/, '');
    +       if (!_.isEmpty(params)) {
    +        fragment = fragment + '?' + $.param(params);
    +       }
    +
    +       FauxtonAPI.navigate(fragment, {trigger: false});
    +       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
    +    }
    +  });
    +
    +  Views.PreviewScreen = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/preview_screen',
    +    className: 'watermark-logo',
    +
    +    initialize: function () {
    +      this.listenTo(FauxtonAPI.Events, 'indexes:newView', this.changeText);
    +    },
    +
    +    changeText: function () {
    +      this.$('.js-status').text('Index is building');
    +    }
    +  });
    +
    +
    +  Views.Row = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/index_row_docular',
    +    className: 'doc-row',
    +    events: {
    +      'click button.delete': 'destroy'
    +    },
    +
    +    destroy: function (event) {
    +      event.preventDefault();
    +
    +      window.alert('Cannot delete a document generated from a view.');
    +    },
    +
    +    beforeRender: function () {
    +      var newLinks = [{
    +        links: [{
    +          title: 'JSON',
    +          icon: 'fonticon-json'
    +        }]
    +      }];
    +
    +      this.insertView('.view-doc-menu', new Components.MenuDropDown({
    +        icon: 'fonticon-drop-down-dots',
    +        links: newLinks,
    --- End diff --
    
    Q: do we care about trailing commas these days? I forget which IE browser chokes on it... but I doubt we support it.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393698
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    +        endpoint: this.endpoint,
    +        documentation: this.documentation
    +      }));
    +
    +      this.advancedOptions = this.insertView('#query-options', new QueryOptions.QueryOptionsTray({
    +        database: this.database,
    +        viewName: this.viewName,
    +        ddocName: this.model.id,
    +        hasReduce: this.hasReduce(),
    +        showStale: true
    +      }));
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('advancedOptions:updateView');
    +    },
    +
    +    hasReduce: function () {
    +
    +    },
    +
    +    updateView: function (event, paramInfo) {
    +       event.preventDefault();
    +
    +       var errorParams = paramInfo.errorParams,
    +           params = paramInfo.params;
    +
    +       if (_.any(errorParams)) {
    +         _.map(errorParams, function (param) {
    +           return FauxtonAPI.addNotification({
    +             msg: 'JSON Parse Error on field: '+param.name,
    +             type: 'error',
    +             clear: true
    +           });
    +         });
    +         FauxtonAPI.addNotification({
    +           msg: 'Make sure that strings are properly quoted and any other values are valid JSON structures',
    +           type: 'warning',
    +           clear: true
    +         });
    +
    +         return false;
    +      }
    +
    +       var fragment = window.location.hash.replace(/\?.*$/, '');
    +       if (!_.isEmpty(params)) {
    +        fragment = fragment + '?' + $.param(params);
    +       }
    +
    +       FauxtonAPI.navigate(fragment, {trigger: false});
    +       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
    +    }
    +  });
    +
    +  Views.PreviewScreen = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/preview_screen',
    +    className: 'watermark-logo',
    +
    +    initialize: function () {
    +      this.listenTo(FauxtonAPI.Events, 'indexes:newView', this.changeText);
    +    },
    +
    +    changeText: function () {
    +      this.$('.js-status').text('Index is building');
    +    }
    +  });
    +
    +
    +  Views.Row = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/index_row_docular',
    +    className: 'doc-row',
    +    events: {
    +      'click button.delete': 'destroy'
    +    },
    +
    +    destroy: function (event) {
    +      event.preventDefault();
    +
    +      window.alert('Cannot delete a document generated from a view.');
    +    },
    +
    +    beforeRender: function () {
    +      var newLinks = [{
    +        links: [{
    +          title: 'JSON',
    +          icon: 'fonticon-json'
    +        }]
    +      }];
    +
    +      this.insertView('.view-doc-menu', new Components.MenuDropDown({
    +        icon: 'fonticon-drop-down-dots',
    +        links: newLinks
    +      }));
    +    },
    +
    +    serialize: function() {
    +      return {
    +        docID: this.model.get('id'),
    +        doc: this.model,
    +        url: this.model.url('app')
    +      };
    +    }
    +  });
    +
    +  Views.IndexCore = FauxtonAPI.View.extend({
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo ? options.ddocInfo.id : '';
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +    },
    +
    +    establish: function () {
    +      if (this.ddocInfo) {
    +        return this.ddocInfo.fetch();
    +      }
    +    },
    +
    +    serialize: function () {
    +      return {
    +        database: this.database.get('id'),
    +        ddocs: this.ddocs,
    +        ddoc: this.model,
    +        ddocName: this.model.id,
    +        viewName: this.viewName,
    +        newView: this.newView,
    +        langTemplates: this.langTemplates.javascript
    +      };
    +    }
    +  });
    +
    +  Views.ViewEditor = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/view_editor',
    +    builtinReduces: ['_sum', '_count', '_stats'],
    +
    +    events: {
    +      'click button.save': 'saveView',
    +      'click button.delete': 'deleteView',
    +      'change select#reduce-function-selector': 'updateReduce',
    +      'click #db-views-tabs-nav': 'toggleIndexNav',
    +      'click .beautify_map':  'beautifyCode',
    +      'click .beautify_reduce':  'beautifyCode'
    +    },
    +
    +    langTemplates: {
    +      'javascript': {
    +        map: 'function(doc) {\n  emit(doc._id, 1);\n}',
    +        reduce: 'function(keys, values, rereduce){\n  if (rereduce){\n    return sum(values);\n  } else {\n    return values.length;\n  }\n}'
    +      }
    +    },
    +
    +    defaultLang: 'javascript',
    +
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo.id;
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +
    +      FauxtonAPI.Events.on('index:delete', this.deleteEvent);
    +    },
    +
    +    establish: function () {
    +      if (!this.ddocInfo) {
    +        return;
    +      }
    +
    +      return this.ddocInfo.fetch();
    +    },
    +
    +    updateValues: function () {
    +      var notification;
    +      if (this.model.changedAttributes()) {
    +        notification = FauxtonAPI.addNotification({
    +          msg: 'Document saved successfully.',
    +          type: 'success',
    +          clear: true
    +        });
    +        this.editor.setValue(this.model.prettyJSON());
    +      }
    +    },
    +
    +    updateReduce: function (event) {
    +      var $ele = $('#reduce-function-selector');
    +      var $reduceContainer = $('.control-group.reduce-function');
    +      if ($ele.val() == 'CUSTOM') {
    +        this.createReduceEditor();
    +        this.reduceEditor.setValue(this.langTemplates.javascript.reduce);
    +        $reduceContainer.show();
    +      } else {
    +        $reduceContainer.hide();
    +      }
    +    },
    +
    +    deleteEvent: function(){
    +      this.deleteView();
    +    },
    +
    +    deleteView: function (event) {
    +      event && event.preventDefault();
    +
    +      if (this.newView) { return alert('Cannot delete a new view.'); }
    +      if (!confirm('Are you sure you want to delete this view?')) { return; }
    +
    +      var that = this,
    +          promise,
    +          viewName = this.$('#index-name').val(),
    +          ddocName = this.$('#ddoc :selected').val(),
    +          ddoc = this.getCurrentDesignDoc();
    +
    +      ddoc.removeDdocView(viewName);
    +
    +      if (ddoc.hasViews()) {
    +        promise = ddoc.save();
    +      } else {
    +        promise = ddoc.destroy();
    +      }
    +
    +      promise.then(function () {
    +        FauxtonAPI.navigate('/database/' + that.database.safeID() + '/_all_docs?limit=' + Databases.DocLimit);
    +        FauxtonAPI.triggerRouteEvent('reloadDesignDocs');
    +      });
    +    },
    +
    +    saveView: function (event) {
    +      var that = this,
    +          json,
    +          notification;
    +
    +      if (event) {
    +        event.preventDefault();
    +      }
    +
    +      $('#dashboard-content').scrollTop(0); //scroll up
    +      //check if the code is valid & the inputs are filled out
    +      if (this.hasValidCode() && this.$('#new-ddoc:visible').val() !=='') {
    +        var mapVal = this.mapEditor.getValue(),
    +        reduceVal = this.reduceVal(),
    +        viewName = this.$('#index-name').val(),
    +        ddoc = this.getCurrentDesignDoc(),
    +        ddocName = ddoc.id;
    +        this.viewNameChange = false;
    +
    +
    +        if (this.viewName !== viewName) {
    +          ddoc.removeDdocView(this.viewName);
    +          this.viewName = viewName;
    +          this.viewNameChange = true;
    +        }
    +
    +        notification = FauxtonAPI.addNotification({
    +          msg: 'Saving document.',
    +          clear: true
    +        });
    +
    +        ddoc.setDdocView(viewName, mapVal, reduceVal);
    +
    +        ddoc.save().then(function () {
    +          //on success
    +          that.afterSave(ddoc, viewName, ddocName);
    +        },
    +        function (xhr) {
    +          //on failure
    +          var responseText = JSON.parse(xhr.responseText).reason;
    +          notification = FauxtonAPI.addNotification({
    +            msg: 'Save failed: ' + responseText,
    +            type: 'error',
    +            clear: true
    +          });
    +        });
    +      } else {
    +        //if nothing is filled out give an error message
    +        var errormessage = (this.$('#new-ddoc:visible').val() ==='')?'Enter a design doc name':'Please fix the Javascript errors and try again.';
    +        notification = FauxtonAPI.addNotification({
    +          msg: errormessage,
    +          type: 'error',
    +          clear: true
    +        });
    +      }
    +    },
    +
    +    afterSave: function (ddoc, viewName, ddocName){
    +      var reduceVal = this.reduceVal();
    +      //add ddoc to the collection
    +      this.ddocs.add(ddoc);
    +
    +      //trigger the EditSaved function on the map editor & reduce editor
    +      this.mapEditor.editSaved();
    +      this.reduceEditor && this.reduceEditor.editSaved();
    +
    +
    +      //show a notification
    +      FauxtonAPI.addNotification({
    +        msg: 'View has been saved.',
    +        type: 'success',
    +        clear: true
    +      });
    +
    +      FauxtonAPI.Events.trigger('indexes:newView');
    +
    +      //if it's new or the name changed (aka created a new doc)
    +      if (this.newView || this.viewNameChange) {
    +        var fragment = '/database/' + this.database.safeID() +'/' + ddoc.safeID() + '/_view/' + app.utils.safeURLName(viewName);
    +
    +        FauxtonAPI.navigate(fragment, {trigger: false});
    +        this.newView = false;
    +        this.ddocID = ddoc.safeID();
    +        this.viewName = viewName;
    +        this.ddocInfo = ddoc;
    +        this.showIndex = true;
    +        this.render();
    +      }
    +
    +      // TODO:// this should change to a trigger because we shouldn't define advanced options in this view
    +      if (this.reduceFunStr !== reduceVal) {
    +        this.reduceFunStr = reduceVal;
    +       // this.advancedOptions.renderOnUpdatehasReduce(this.hasReduce());
    +      }
    +
    +      // Route Event will reload the right content
    +      FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
    +    },
    +
    +    getCurrentDesignDoc: function () {
    +      return this.designDocSelector.getCurrentDesignDoc();
    +    },
    +
    +    isCustomReduceEnabled: function () {
    +      return $('#reduce-function-selector').val() == 'CUSTOM';
    +    },
    +
    +    mapVal: function () {
    +      if (this.mapEditor) {
    +        return this.mapEditor.getValue();
    +      }
    +
    +      return this.$('#map-function').text();
    +    },
    +
    +    reduceVal: function () {
    +      var reduceOption = this.$('#reduce-function-selector :selected').val(),
    +      reduceVal = '';
    +
    +      if (reduceOption === 'CUSTOM') {
    +        if (!this.reduceEditor) { this.createReduceEditor(); }
    +        reduceVal = this.reduceEditor.getValue();
    +      } else if ( reduceOption !== 'NONE') {
    +        reduceVal = reduceOption;
    +      }
    +
    +      return reduceVal;
    +    },
    +
    +    hasValidCode: function () {
    +      return _.every(['mapEditor', 'reduceEditor'], function(editorName) {
    +        var editor = this[editorName];
    +        if (editorName === 'reduceEditor' && ! this.isCustomReduceEnabled()) {
    +          return true;
    +        }
    +        return editor.hadValidCode();
    +      }, this);
    +    },
    +
    +    serialize: function () {
    +      return {
    +        database: this.database.get('id'),
    +        ddocs: this.ddocs,
    +        ddoc: this.model,
    +        ddocName: this.model.id,
    +        viewName: this.viewName,
    +        reduceFunStr: this.reduceFunStr,
    +        isCustomReduce: this.hasCustomReduce(),
    +        newView: this.newView,
    +        langTemplates: this.langTemplates.javascript
    +      };
    +    },
    +
    +    hasCustomReduce: function () {
    +      return this.reduceFunStr && ! _.contains(this.builtinReduces, this.reduceFunStr);
    +    },
    +
    +    hasReduce: function () {
    +      return this.reduceFunStr || false;
    +    },
    +
    +    createReduceEditor: function () {
    +      if (this.reduceEditor) {
    +        this.reduceEditor.remove();
    +      }
    +
    +      this.reduceEditor = new Components.Editor({
    +        editorId: 'reduce-function',
    +        mode: 'javascript',
    +        couchJSHINT: true
    +      });
    +      this.reduceEditor.render();
    +
    +      if (this.reduceEditor.getLines() === 1){
    +        this.$('.beautify_reduce').removeClass('hide');
    +        $('.beautify-tooltip').tooltip();
    +      }
    +    },
    +
    +    beforeRender: function () {
    +
    +      if (this.newView) {
    +        this.reduceFunStr = '';
    +        if (this.ddocs.length === 0) {
    +          this.model = new Documents.Doc(null, {database: this.database});
    +        } else {
    +          this.model = this.ddocs.first().dDocModel();
    +        }
    +        this.ddocID = this.model.id;
    +      } else {
    +        var ddocDecode = decodeURIComponent(this.ddocID);
    +        this.model = this.ddocs.get(this.ddocID).dDocModel();
    +        this.reduceFunStr = this.model.viewHasReduce(this.viewName);
    +      }
    +
    +      var viewFilters = FauxtonAPI.getExtensions('sidebar:viewFilters'),
    +          filteredModels = this.ddocs.models,
    +          designDocs = this.ddocs.clone();
    +
    +      if (!_.isEmpty(viewFilters)) {
    +        _.each(viewFilters, function (filter) {
    +          filteredModels = _.filter(filteredModels, filter);
    +        });
    +        designDocs.reset(filteredModels, {silent: true});
    +      }
    +
    +      this.designDocSelector = this.setView('.design-doc-group', new Views.DesignDocSelector({
    +        collection: designDocs,
    +        newView: this.newView,
    +        ddocName: this.currentDdoc || this.model.id,
    +        database: this.database
    +      }));
    +
    +    },
    +
    +    afterRender: function () {
    +      //TODO: have this happen on a trigger once we move advanced options to the header
    --- End diff --
    
    Is this still relevant?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#issuecomment-60566146
  
    @robertkowalski, This PR needs a fair amount of work. Some bugs I noticed.
    * The icons when I click on any 'plus` menu dropdown are bigger.
    * I cannot query a view. The query dropdown is not there. 
    * When I click add new secondary view next to a design doc, The new view form does not have the design doc section prefilled with the design doc. I also cannot select any design docs.
    * When I edit a view I cannot select a different design doc - I'm not sure if this is intentional.
    



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#issuecomment-60592465
  
    Hi Garren, thanks for the feedback, I changed the code.
    
    > The icons when I click on any 'plus` menu dropdown are bigger.
    
    Should be fixed now
    
    > I cannot query a view. The query dropdown is not there.
    
    I removed the Query-Functionality from the New-View windows in order to get the work in a mergeable state. There is some work left if we want to query views inside the same view in which we create new views. The Query-Tray needs to be a component for that, same for the RightHeader.
    
    > When I click add new secondary view next to a design doc, The new view form does not have the design doc section prefilled with the design doc. I also cannot select any design docs.
    
    Let's have a short chat about that, did not know about that feature
    
    > When I edit a view I cannot select a different design doc - I'm not sure if this is intentional.
    
    I like the idea, but I haven't seen any this in the previous work
    
    Let's have a short chat today about the scope of that branch.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393721
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    +        endpoint: this.endpoint,
    +        documentation: this.documentation
    +      }));
    +
    +      this.advancedOptions = this.insertView('#query-options', new QueryOptions.QueryOptionsTray({
    +        database: this.database,
    +        viewName: this.viewName,
    +        ddocName: this.model.id,
    +        hasReduce: this.hasReduce(),
    +        showStale: true
    +      }));
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('advancedOptions:updateView');
    +    },
    +
    +    hasReduce: function () {
    +
    +    },
    +
    +    updateView: function (event, paramInfo) {
    +       event.preventDefault();
    +
    +       var errorParams = paramInfo.errorParams,
    +           params = paramInfo.params;
    +
    +       if (_.any(errorParams)) {
    +         _.map(errorParams, function (param) {
    +           return FauxtonAPI.addNotification({
    +             msg: 'JSON Parse Error on field: '+param.name,
    +             type: 'error',
    +             clear: true
    +           });
    +         });
    +         FauxtonAPI.addNotification({
    +           msg: 'Make sure that strings are properly quoted and any other values are valid JSON structures',
    +           type: 'warning',
    +           clear: true
    +         });
    +
    +         return false;
    +      }
    +
    +       var fragment = window.location.hash.replace(/\?.*$/, '');
    +       if (!_.isEmpty(params)) {
    +        fragment = fragment + '?' + $.param(params);
    +       }
    +
    +       FauxtonAPI.navigate(fragment, {trigger: false});
    +       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
    +    }
    +  });
    +
    +  Views.PreviewScreen = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/preview_screen',
    +    className: 'watermark-logo',
    +
    +    initialize: function () {
    +      this.listenTo(FauxtonAPI.Events, 'indexes:newView', this.changeText);
    +    },
    +
    +    changeText: function () {
    +      this.$('.js-status').text('Index is building');
    +    }
    +  });
    +
    +
    +  Views.Row = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/index_row_docular',
    +    className: 'doc-row',
    +    events: {
    +      'click button.delete': 'destroy'
    +    },
    +
    +    destroy: function (event) {
    +      event.preventDefault();
    +
    +      window.alert('Cannot delete a document generated from a view.');
    +    },
    +
    +    beforeRender: function () {
    +      var newLinks = [{
    +        links: [{
    +          title: 'JSON',
    +          icon: 'fonticon-json'
    +        }]
    +      }];
    +
    +      this.insertView('.view-doc-menu', new Components.MenuDropDown({
    +        icon: 'fonticon-drop-down-dots',
    +        links: newLinks
    +      }));
    +    },
    +
    +    serialize: function() {
    +      return {
    +        docID: this.model.get('id'),
    +        doc: this.model,
    +        url: this.model.url('app')
    +      };
    +    }
    +  });
    +
    +  Views.IndexCore = FauxtonAPI.View.extend({
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo ? options.ddocInfo.id : '';
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +    },
    +
    +    establish: function () {
    +      if (this.ddocInfo) {
    +        return this.ddocInfo.fetch();
    +      }
    +    },
    +
    +    serialize: function () {
    +      return {
    +        database: this.database.get('id'),
    +        ddocs: this.ddocs,
    +        ddoc: this.model,
    +        ddocName: this.model.id,
    +        viewName: this.viewName,
    +        newView: this.newView,
    +        langTemplates: this.langTemplates.javascript
    +      };
    +    }
    +  });
    +
    +  Views.ViewEditor = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/view_editor',
    +    builtinReduces: ['_sum', '_count', '_stats'],
    +
    +    events: {
    +      'click button.save': 'saveView',
    +      'click button.delete': 'deleteView',
    +      'change select#reduce-function-selector': 'updateReduce',
    +      'click #db-views-tabs-nav': 'toggleIndexNav',
    +      'click .beautify_map':  'beautifyCode',
    +      'click .beautify_reduce':  'beautifyCode'
    +    },
    +
    +    langTemplates: {
    +      'javascript': {
    +        map: 'function(doc) {\n  emit(doc._id, 1);\n}',
    +        reduce: 'function(keys, values, rereduce){\n  if (rereduce){\n    return sum(values);\n  } else {\n    return values.length;\n  }\n}'
    +      }
    +    },
    +
    +    defaultLang: 'javascript',
    +
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo.id;
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +
    +      FauxtonAPI.Events.on('index:delete', this.deleteEvent);
    +    },
    +
    +    establish: function () {
    +      if (!this.ddocInfo) {
    +        return;
    +      }
    +
    +      return this.ddocInfo.fetch();
    +    },
    +
    +    updateValues: function () {
    +      var notification;
    +      if (this.model.changedAttributes()) {
    +        notification = FauxtonAPI.addNotification({
    +          msg: 'Document saved successfully.',
    +          type: 'success',
    +          clear: true
    +        });
    +        this.editor.setValue(this.model.prettyJSON());
    +      }
    +    },
    +
    +    updateReduce: function (event) {
    +      var $ele = $('#reduce-function-selector');
    +      var $reduceContainer = $('.control-group.reduce-function');
    +      if ($ele.val() == 'CUSTOM') {
    +        this.createReduceEditor();
    +        this.reduceEditor.setValue(this.langTemplates.javascript.reduce);
    +        $reduceContainer.show();
    +      } else {
    +        $reduceContainer.hide();
    +      }
    +    },
    +
    +    deleteEvent: function(){
    +      this.deleteView();
    +    },
    +
    +    deleteView: function (event) {
    +      event && event.preventDefault();
    +
    +      if (this.newView) { return alert('Cannot delete a new view.'); }
    +      if (!confirm('Are you sure you want to delete this view?')) { return; }
    +
    +      var that = this,
    +          promise,
    +          viewName = this.$('#index-name').val(),
    +          ddocName = this.$('#ddoc :selected').val(),
    +          ddoc = this.getCurrentDesignDoc();
    +
    +      ddoc.removeDdocView(viewName);
    +
    +      if (ddoc.hasViews()) {
    +        promise = ddoc.save();
    +      } else {
    +        promise = ddoc.destroy();
    +      }
    +
    +      promise.then(function () {
    +        FauxtonAPI.navigate('/database/' + that.database.safeID() + '/_all_docs?limit=' + Databases.DocLimit);
    +        FauxtonAPI.triggerRouteEvent('reloadDesignDocs');
    +      });
    +    },
    +
    +    saveView: function (event) {
    +      var that = this,
    +          json,
    +          notification;
    +
    +      if (event) {
    +        event.preventDefault();
    +      }
    +
    +      $('#dashboard-content').scrollTop(0); //scroll up
    +      //check if the code is valid & the inputs are filled out
    +      if (this.hasValidCode() && this.$('#new-ddoc:visible').val() !=='') {
    +        var mapVal = this.mapEditor.getValue(),
    +        reduceVal = this.reduceVal(),
    +        viewName = this.$('#index-name').val(),
    +        ddoc = this.getCurrentDesignDoc(),
    +        ddocName = ddoc.id;
    +        this.viewNameChange = false;
    +
    +
    +        if (this.viewName !== viewName) {
    +          ddoc.removeDdocView(this.viewName);
    +          this.viewName = viewName;
    +          this.viewNameChange = true;
    +        }
    +
    +        notification = FauxtonAPI.addNotification({
    +          msg: 'Saving document.',
    +          clear: true
    +        });
    +
    +        ddoc.setDdocView(viewName, mapVal, reduceVal);
    +
    +        ddoc.save().then(function () {
    +          //on success
    +          that.afterSave(ddoc, viewName, ddocName);
    +        },
    +        function (xhr) {
    +          //on failure
    +          var responseText = JSON.parse(xhr.responseText).reason;
    +          notification = FauxtonAPI.addNotification({
    +            msg: 'Save failed: ' + responseText,
    +            type: 'error',
    +            clear: true
    +          });
    +        });
    +      } else {
    +        //if nothing is filled out give an error message
    +        var errormessage = (this.$('#new-ddoc:visible').val() ==='')?'Enter a design doc name':'Please fix the Javascript errors and try again.';
    +        notification = FauxtonAPI.addNotification({
    +          msg: errormessage,
    +          type: 'error',
    +          clear: true
    +        });
    +      }
    +    },
    +
    +    afterSave: function (ddoc, viewName, ddocName){
    +      var reduceVal = this.reduceVal();
    +      //add ddoc to the collection
    +      this.ddocs.add(ddoc);
    +
    +      //trigger the EditSaved function on the map editor & reduce editor
    +      this.mapEditor.editSaved();
    +      this.reduceEditor && this.reduceEditor.editSaved();
    +
    +
    +      //show a notification
    +      FauxtonAPI.addNotification({
    +        msg: 'View has been saved.',
    +        type: 'success',
    +        clear: true
    +      });
    +
    +      FauxtonAPI.Events.trigger('indexes:newView');
    +
    +      //if it's new or the name changed (aka created a new doc)
    +      if (this.newView || this.viewNameChange) {
    +        var fragment = '/database/' + this.database.safeID() +'/' + ddoc.safeID() + '/_view/' + app.utils.safeURLName(viewName);
    +
    +        FauxtonAPI.navigate(fragment, {trigger: false});
    +        this.newView = false;
    +        this.ddocID = ddoc.safeID();
    +        this.viewName = viewName;
    +        this.ddocInfo = ddoc;
    +        this.showIndex = true;
    +        this.render();
    +      }
    +
    +      // TODO:// this should change to a trigger because we shouldn't define advanced options in this view
    +      if (this.reduceFunStr !== reduceVal) {
    +        this.reduceFunStr = reduceVal;
    +       // this.advancedOptions.renderOnUpdatehasReduce(this.hasReduce());
    +      }
    +
    +      // Route Event will reload the right content
    +      FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
    +    },
    +
    +    getCurrentDesignDoc: function () {
    +      return this.designDocSelector.getCurrentDesignDoc();
    +    },
    +
    +    isCustomReduceEnabled: function () {
    +      return $('#reduce-function-selector').val() == 'CUSTOM';
    +    },
    +
    +    mapVal: function () {
    +      if (this.mapEditor) {
    +        return this.mapEditor.getValue();
    +      }
    +
    +      return this.$('#map-function').text();
    +    },
    +
    +    reduceVal: function () {
    +      var reduceOption = this.$('#reduce-function-selector :selected').val(),
    +      reduceVal = '';
    +
    +      if (reduceOption === 'CUSTOM') {
    +        if (!this.reduceEditor) { this.createReduceEditor(); }
    +        reduceVal = this.reduceEditor.getValue();
    +      } else if ( reduceOption !== 'NONE') {
    +        reduceVal = reduceOption;
    +      }
    +
    +      return reduceVal;
    +    },
    +
    +    hasValidCode: function () {
    +      return _.every(['mapEditor', 'reduceEditor'], function(editorName) {
    +        var editor = this[editorName];
    +        if (editorName === 'reduceEditor' && ! this.isCustomReduceEnabled()) {
    +          return true;
    +        }
    +        return editor.hadValidCode();
    +      }, this);
    +    },
    +
    +    serialize: function () {
    +      return {
    +        database: this.database.get('id'),
    +        ddocs: this.ddocs,
    +        ddoc: this.model,
    +        ddocName: this.model.id,
    +        viewName: this.viewName,
    +        reduceFunStr: this.reduceFunStr,
    +        isCustomReduce: this.hasCustomReduce(),
    +        newView: this.newView,
    +        langTemplates: this.langTemplates.javascript
    +      };
    +    },
    +
    +    hasCustomReduce: function () {
    +      return this.reduceFunStr && ! _.contains(this.builtinReduces, this.reduceFunStr);
    +    },
    +
    +    hasReduce: function () {
    +      return this.reduceFunStr || false;
    +    },
    +
    +    createReduceEditor: function () {
    +      if (this.reduceEditor) {
    +        this.reduceEditor.remove();
    +      }
    +
    +      this.reduceEditor = new Components.Editor({
    +        editorId: 'reduce-function',
    +        mode: 'javascript',
    +        couchJSHINT: true
    +      });
    +      this.reduceEditor.render();
    +
    +      if (this.reduceEditor.getLines() === 1){
    +        this.$('.beautify_reduce').removeClass('hide');
    +        $('.beautify-tooltip').tooltip();
    +      }
    +    },
    +
    +    beforeRender: function () {
    +
    +      if (this.newView) {
    +        this.reduceFunStr = '';
    +        if (this.ddocs.length === 0) {
    +          this.model = new Documents.Doc(null, {database: this.database});
    +        } else {
    +          this.model = this.ddocs.first().dDocModel();
    +        }
    +        this.ddocID = this.model.id;
    +      } else {
    +        var ddocDecode = decodeURIComponent(this.ddocID);
    +        this.model = this.ddocs.get(this.ddocID).dDocModel();
    +        this.reduceFunStr = this.model.viewHasReduce(this.viewName);
    +      }
    +
    +      var viewFilters = FauxtonAPI.getExtensions('sidebar:viewFilters'),
    +          filteredModels = this.ddocs.models,
    +          designDocs = this.ddocs.clone();
    +
    +      if (!_.isEmpty(viewFilters)) {
    +        _.each(viewFilters, function (filter) {
    +          filteredModels = _.filter(filteredModels, filter);
    +        });
    +        designDocs.reset(filteredModels, {silent: true});
    +      }
    +
    +      this.designDocSelector = this.setView('.design-doc-group', new Views.DesignDocSelector({
    +        collection: designDocs,
    +        newView: this.newView,
    +        ddocName: this.currentDdoc || this.model.id,
    +        database: this.database
    +      }));
    +
    +    },
    +
    +    afterRender: function () {
    +      //TODO: have this happen on a trigger once we move advanced options to the header
    +      // if (this.params && !this.newView) {
    +      //   this.advancedOptions.updateFromParams(this.params);
    +      // }
    +
    +      this.designDocSelector.updateDesignDoc();
    +      this.showEditors();
    +      this.showIndex = false;
    +
    +    },
    +
    +    showEditors: function () {
    +      this.mapEditor = new Components.Editor({
    +        editorId: 'map-function',
    +        mode: 'javascript',
    +        couchJSHINT: true
    +      });
    +      this.mapEditor.render();
    +
    +      if (this.hasCustomReduce()) {
    +        this.createReduceEditor();
    +      } else {
    +        $('.control-group.reduce-function').hide();
    +      }
    +
    +      if (this.newView) {
    +        this.mapEditor.setValue(this.langTemplates[this.defaultLang].map);
    +        //Use a built in view by default
    +        //this.reduceEditor.setValue(this.langTemplates[this.defaultLang].reduce);
    +      }
    +
    +      this.mapEditor.editSaved();
    +      this.reduceEditor && this.reduceEditor.editSaved();
    +
    +      if (this.mapEditor.getLines() === 1){
    +        this.$('.beautify_map').removeClass('hide');
    +        $('.beautify-tooltip').tooltip();
    +      }
    +    },
    +
    +    beautifyCode: function (e) {
    +      e.preventDefault();
    +      var targetEditor = $(e.currentTarget).hasClass('beautify_reduce')?this.reduceEditor:this.mapEditor;
    +      var beautifiedCode = beautify(targetEditor.getValue());
    +      targetEditor.setValue(beautifiedCode);
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('index:delete');
    --- End diff --
    
    If we use `listenTo` in this view we don't need to unbind.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by garrensmith <gi...@git.apache.org>.
Github user garrensmith commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19393636
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    +        endpoint: this.endpoint,
    +        documentation: this.documentation
    +      }));
    +
    +      this.advancedOptions = this.insertView('#query-options', new QueryOptions.QueryOptionsTray({
    +        database: this.database,
    +        viewName: this.viewName,
    +        ddocName: this.model.id,
    +        hasReduce: this.hasReduce(),
    +        showStale: true
    +      }));
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('advancedOptions:updateView');
    +    },
    +
    +    hasReduce: function () {
    +
    +    },
    +
    +    updateView: function (event, paramInfo) {
    +       event.preventDefault();
    +
    +       var errorParams = paramInfo.errorParams,
    +           params = paramInfo.params;
    +
    +       if (_.any(errorParams)) {
    +         _.map(errorParams, function (param) {
    +           return FauxtonAPI.addNotification({
    +             msg: 'JSON Parse Error on field: '+param.name,
    +             type: 'error',
    +             clear: true
    +           });
    +         });
    +         FauxtonAPI.addNotification({
    +           msg: 'Make sure that strings are properly quoted and any other values are valid JSON structures',
    +           type: 'warning',
    +           clear: true
    +         });
    +
    +         return false;
    +      }
    +
    +       var fragment = window.location.hash.replace(/\?.*$/, '');
    +       if (!_.isEmpty(params)) {
    +        fragment = fragment + '?' + $.param(params);
    +       }
    +
    +       FauxtonAPI.navigate(fragment, {trigger: false});
    +       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
    +    }
    +  });
    +
    +  Views.PreviewScreen = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/preview_screen',
    +    className: 'watermark-logo',
    +
    +    initialize: function () {
    +      this.listenTo(FauxtonAPI.Events, 'indexes:newView', this.changeText);
    +    },
    +
    +    changeText: function () {
    +      this.$('.js-status').text('Index is building');
    +    }
    +  });
    +
    +
    +  Views.Row = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/index_row_docular',
    +    className: 'doc-row',
    +    events: {
    +      'click button.delete': 'destroy'
    +    },
    +
    +    destroy: function (event) {
    +      event.preventDefault();
    +
    +      window.alert('Cannot delete a document generated from a view.');
    +    },
    +
    +    beforeRender: function () {
    +      var newLinks = [{
    +        links: [{
    +          title: 'JSON',
    +          icon: 'fonticon-json'
    +        }]
    +      }];
    +
    +      this.insertView('.view-doc-menu', new Components.MenuDropDown({
    +        icon: 'fonticon-drop-down-dots',
    +        links: newLinks
    +      }));
    +    },
    +
    +    serialize: function() {
    +      return {
    +        docID: this.model.get('id'),
    +        doc: this.model,
    +        url: this.model.url('app')
    +      };
    +    }
    +  });
    +
    +  Views.IndexCore = FauxtonAPI.View.extend({
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo ? options.ddocInfo.id : '';
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +    },
    +
    +    establish: function () {
    +      if (this.ddocInfo) {
    +        return this.ddocInfo.fetch();
    +      }
    +    },
    +
    +    serialize: function () {
    +      return {
    +        database: this.database.get('id'),
    +        ddocs: this.ddocs,
    +        ddoc: this.model,
    +        ddocName: this.model.id,
    +        viewName: this.viewName,
    +        newView: this.newView,
    +        langTemplates: this.langTemplates.javascript
    +      };
    +    }
    +  });
    +
    +  Views.ViewEditor = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/view_editor',
    +    builtinReduces: ['_sum', '_count', '_stats'],
    +
    +    events: {
    +      'click button.save': 'saveView',
    +      'click button.delete': 'deleteView',
    +      'change select#reduce-function-selector': 'updateReduce',
    +      'click #db-views-tabs-nav': 'toggleIndexNav',
    +      'click .beautify_map':  'beautifyCode',
    +      'click .beautify_reduce':  'beautifyCode'
    +    },
    +
    +    langTemplates: {
    +      'javascript': {
    +        map: 'function(doc) {\n  emit(doc._id, 1);\n}',
    +        reduce: 'function(keys, values, rereduce){\n  if (rereduce){\n    return sum(values);\n  } else {\n    return values.length;\n  }\n}'
    +      }
    +    },
    +
    +    defaultLang: 'javascript',
    +
    +    initialize: function (options) {
    +      this.newView = options.newView || false;
    +      this.ddocs = options.ddocs;
    +      this.params = options.params;
    +      this.database = options.database;
    +      this.currentDdoc = options.currentddoc;
    +
    +      if (this.newView) {
    +        this.viewName = 'newView';
    +      } else {
    +        this.ddocID = options.ddocInfo.id;
    +        this.viewName = options.viewName;
    +        this.ddocInfo = new Documents.DdocInfo({_id: this.ddocID},{database: this.database});
    +      }
    +
    +      this.showIndex = false;
    +      _.bindAll(this);
    +
    +      FauxtonAPI.Events.on('index:delete', this.deleteEvent);
    +    },
    +
    +    establish: function () {
    +      if (!this.ddocInfo) {
    +        return;
    +      }
    +
    +      return this.ddocInfo.fetch();
    +    },
    +
    +    updateValues: function () {
    +      var notification;
    +      if (this.model.changedAttributes()) {
    +        notification = FauxtonAPI.addNotification({
    +          msg: 'Document saved successfully.',
    +          type: 'success',
    +          clear: true
    +        });
    +        this.editor.setValue(this.model.prettyJSON());
    +      }
    +    },
    +
    +    updateReduce: function (event) {
    +      var $ele = $('#reduce-function-selector');
    +      var $reduceContainer = $('.control-group.reduce-function');
    +      if ($ele.val() == 'CUSTOM') {
    +        this.createReduceEditor();
    +        this.reduceEditor.setValue(this.langTemplates.javascript.reduce);
    +        $reduceContainer.show();
    +      } else {
    +        $reduceContainer.hide();
    +      }
    +    },
    +
    +    deleteEvent: function(){
    +      this.deleteView();
    +    },
    +
    +    deleteView: function (event) {
    +      event && event.preventDefault();
    +
    +      if (this.newView) { return alert('Cannot delete a new view.'); }
    +      if (!confirm('Are you sure you want to delete this view?')) { return; }
    +
    +      var that = this,
    +          promise,
    +          viewName = this.$('#index-name').val(),
    +          ddocName = this.$('#ddoc :selected').val(),
    +          ddoc = this.getCurrentDesignDoc();
    +
    +      ddoc.removeDdocView(viewName);
    +
    +      if (ddoc.hasViews()) {
    +        promise = ddoc.save();
    +      } else {
    +        promise = ddoc.destroy();
    +      }
    +
    +      promise.then(function () {
    +        FauxtonAPI.navigate('/database/' + that.database.safeID() + '/_all_docs?limit=' + Databases.DocLimit);
    +        FauxtonAPI.triggerRouteEvent('reloadDesignDocs');
    +      });
    +    },
    +
    +    saveView: function (event) {
    +      var that = this,
    +          json,
    +          notification;
    +
    +      if (event) {
    +        event.preventDefault();
    +      }
    +
    +      $('#dashboard-content').scrollTop(0); //scroll up
    +      //check if the code is valid & the inputs are filled out
    +      if (this.hasValidCode() && this.$('#new-ddoc:visible').val() !=='') {
    +        var mapVal = this.mapEditor.getValue(),
    +        reduceVal = this.reduceVal(),
    +        viewName = this.$('#index-name').val(),
    +        ddoc = this.getCurrentDesignDoc(),
    +        ddocName = ddoc.id;
    +        this.viewNameChange = false;
    +
    --- End diff --
    
    I don't think we need two line breaks here.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by robertkowalski <gi...@git.apache.org>.
Github user robertkowalski commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19266062
  
    --- Diff: app/addons/indexes/views.js ---
    @@ -0,0 +1,641 @@
    +// 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.
    +
    +define([
    +  'app',
    +
    +  'api',
    +  'addons/fauxton/components',
    +
    +  'addons/documents/resources',
    +  'addons/databases/resources',
    +  'addons/pouchdb/base',
    +  //views
    +  'addons/documents/views-queryoptions',
    +  // Libs
    +  'addons/fauxton/resizeColumns',
    +
    +  // Plugins
    +  'plugins/beautify',
    +  'plugins/prettify'
    +],
    +
    +function (app, FauxtonAPI, Components, Documents, Databases, pouchdb,
    +         QueryOptions, resizeColumns, beautify, prettify) {
    +
    +  var Views = {};
    +
    +  Views.RightHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/indexes/templates/header_right',
    +
    +    initialize: function (options) {
    +      _.bindAll(this);
    +      this.database = options.database;
    +      this.title = options.title;
    +      this.api = options.api;
    +      this.endpoint = options.endpoint;
    +      this.documentation = options.documentation;
    +      FauxtonAPI.Events.on('advancedOptions:updateView', this.updateView);
    +    },
    +
    +    updateApiUrl: function (api) {
    +      //this will update the api bar when the route changes
    +      //you can find the method that updates it in components.js Components.ApiBar()
    +      this.apiBar && this.apiBar.update(api);
    +    },
    +
    +    beforeRender: function () {
    +      this.apiBar = this.insertView('#header-api-bar', new Components.ApiBar({
    +        endpoint: this.endpoint,
    +        documentation: this.documentation
    +      }));
    +
    +      this.advancedOptions = this.insertView('#query-options', new QueryOptions.QueryOptionsTray({
    +        database: this.database,
    +        viewName: this.viewName,
    +        ddocName: this.model.id,
    +        hasReduce: this.hasReduce(),
    +        showStale: true
    +      }));
    +    },
    +
    +    cleanup: function () {
    +      FauxtonAPI.Events.unbind('advancedOptions:updateView');
    +    },
    +
    +    hasReduce: function () {
    +
    +    },
    +
    +    updateView: function (event, paramInfo) {
    +       event.preventDefault();
    +
    +       var errorParams = paramInfo.errorParams,
    +           params = paramInfo.params;
    +
    +       if (_.any(errorParams)) {
    +         _.map(errorParams, function (param) {
    +           return FauxtonAPI.addNotification({
    +             msg: 'JSON Parse Error on field: '+param.name,
    +             type: 'error',
    +             clear: true
    +           });
    +         });
    +         FauxtonAPI.addNotification({
    +           msg: 'Make sure that strings are properly quoted and any other values are valid JSON structures',
    +           type: 'warning',
    +           clear: true
    +         });
    +
    +         return false;
    +      }
    +
    +       var fragment = window.location.hash.replace(/\?.*$/, '');
    +       if (!_.isEmpty(params)) {
    +        fragment = fragment + '?' + $.param(params);
    +       }
    +
    +       FauxtonAPI.navigate(fragment, {trigger: false});
    +       FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
    +    }
    +  });
    +
    +  Views.PreviewScreen = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/preview_screen',
    +    className: 'watermark-logo',
    +
    +    initialize: function () {
    +      this.listenTo(FauxtonAPI.Events, 'indexes:newView', this.changeText);
    +    },
    +
    +    changeText: function () {
    +      this.$('.js-status').text('Index is building');
    +    }
    +  });
    +
    +
    +  Views.Row = FauxtonAPI.View.extend({
    +    template: 'addons/indexes/templates/index_row_docular',
    +    className: 'doc-row',
    +    events: {
    +      'click button.delete': 'destroy'
    +    },
    +
    +    destroy: function (event) {
    +      event.preventDefault();
    +
    +      window.alert('Cannot delete a document generated from a view.');
    +    },
    +
    +    beforeRender: function () {
    +      var newLinks = [{
    +        links: [{
    +          title: 'JSON',
    +          icon: 'fonticon-json'
    +        }]
    +      }];
    +
    +      this.insertView('.view-doc-menu', new Components.MenuDropDown({
    +        icon: 'fonticon-drop-down-dots',
    +        links: newLinks,
    --- End diff --
    
    I avoid them because I am used to it.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] couchdb-fauxton pull request: Port View Indexes work from PR #33

Posted by benkeen <gi...@git.apache.org>.
Github user benkeen commented on a diff in the pull request:

    https://github.com/apache/couchdb-fauxton/pull/106#discussion_r19228651
  
    --- Diff: app/addons/documents/views.js ---
    @@ -119,6 +119,47 @@ function(app, FauxtonAPI, Components, Documents, Databases, Views, QueryOptions)
         }
       });
     
    +  Views.SelectMenuHeader = FauxtonAPI.View.extend({
    +    className: 'header-right',
    +    template: 'addons/documents/templates/select_doc_menu',
    +    events: {
    +      'click button.all': 'selectAll',
    --- End diff --
    
    button.js-all ? Not a big deal.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---