You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2014/01/13 10:57:59 UTC
[2/8] Fauxton: move modules to addons
http://git-wip-us.apache.org/repos/asf/couchdb/blob/89810cce/src/fauxton/app/modules/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js
deleted file mode 100644
index 435ed5e..0000000
--- a/src/fauxton/app/modules/documents/routes.js
+++ /dev/null
@@ -1,409 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-define([
- "app",
-
- "api",
-
- // Modules
- "modules/documents/views",
- "modules/databases/base"
-],
-
-function(app, FauxtonAPI, Documents, Databases) {
-
- var DocEditorRouteObject = FauxtonAPI.RouteObject.extend({
- layout: "one_pane",
- disableLoader: true,
- selectedHeader: "Databases",
- initialize: function(route, masterLayout, options) {
- var databaseName = options[0];
- this.docID = options[1]||'new';
-
- this.database = this.database || new Databases.Model({id: databaseName});
- this.doc = new Documents.Doc({
- _id: this.docID
- }, {
- database: this.database
- });
-
- this.tabsView = this.setView("#tabs", new Documents.Views.FieldEditorTabs({
- disableLoader: true,
- selected: "code_editor",
- model: this.doc
- }));
-
- },
-
- routes: {
- // We are hiding the field_editor for this first release
- // "database/:database/:doc/field_editor": "field_editor",
- "database/:database/:doc/code_editor": "code_editor",
- "database/:database/:doc": "code_editor"
- },
-
- events: {
- "route:reRenderDoc": "reRenderDoc",
- "route:duplicateDoc": "duplicateDoc"
- },
-
- crumbs: function() {
- return [
- {"name": this.database.id, "link": Databases.databaseUrl(this.database)},
- {"name": this.docID, "link": "#"}
- ];
- },
-
- code_editor: function (database, doc) {
- this.tabsView.updateSelected('code_editor');
-
- this.docView = this.setView("#dashboard-content", new Documents.Views.Doc({
- model: this.doc,
- database: this.database
- }));
- },
-
- reRenderDoc: function () {
- this.docView.forceRender();
- },
-
- field_editor: function(events) {
- this.tabsView.updateSelected('field_editor');
- this.docView = this.setView("#dashboard-content", new Documents.Views.DocFieldEditor({
- model: this.doc
- }));
- },
-
- duplicateDoc: function (newId) {
- var doc = this.doc,
- docView = this.docView,
- database = this.database;
-
- doc.copy(newId).then(function () {
- doc.set({_id: newId});
- docView.forceRender();
- FauxtonAPI.navigate('/database/' + database.safeID() + '/' + app.mixins.safeURLName(newId), {trigger: true});
- FauxtonAPI.addNotification({
- msg: "Document has been duplicated."
- });
-
- }, function (error) {
- var errorMsg = "Could not duplicate document, reason: " + error.responseText + ".";
- FauxtonAPI.addNotification({
- msg: errorMsg,
- type: "error"
- });
- });
- },
-
- apiUrl: function() {
- return [this.doc.url("apiurl"), this.doc.documentation()];
- }
- });
-
- var NewDocEditorRouteObject = DocEditorRouteObject.extend({
- initialize: function (route, masterLayout, options) {
- var databaseName = options[0];
-
- this.database = this.database || new Databases.Model({id: databaseName});
- this.doc = new Documents.NewDoc(null,{
- database: this.database
- });
-
- this.tabsView = this.setView("#tabs", new Documents.Views.FieldEditorTabs({
- selected: "code_editor",
- model: this.doc
- }));
-
- },
- crumbs: function() {
- return [
- {"name": this.database.id, "link": Databases.databaseUrl(this.database)},
- {"name": "New", "link": "#"}
- ];
- },
- routes: {
- "database/:database/new": "code_editor"
- },
- selectedHeader: "Databases",
-
- });
-
- var DocumentsRouteObject = FauxtonAPI.RouteObject.extend({
- layout: "with_tabs_sidebar",
- selectedHeader: "Databases",
- routes: {
- "database/:database/_all_docs(:extra)": "allDocs",
- "database/:database/_design/:ddoc/_view/:view": {
- route: "viewFn",
- roles: ['_admin']
- },
- "database/:database/new_view": "newViewEditor"
- },
-
- events: {
- "route:updateAllDocs": "updateAllDocsFromView",
- "route:updatePreviewDocs": "updateAllDocsFromPreview",
- "route:reloadDesignDocs": "reloadDesignDocs",
- "route:paginate": "paginate"
- },
-
- initialize: function (route, masterLayout, options) {
- var docOptions = app.getParams();
- docOptions.include_docs = true;
-
- this.databaseName = options[0];
-
- this.data = {
- database: new Databases.Model({id:this.databaseName})
- };
-
- this.data.designDocs = new Documents.AllDocs(null, {
- database: this.data.database,
- params: {startkey: '"_design"',
- endkey: '"_design1"',
- include_docs: true}
- });
-
- this.sidebar = this.setView("#sidebar-content", new Documents.Views.Sidebar({
- collection: this.data.designDocs,
- database: this.data.database
- }));
- },
-
- establish: function () {
- return this.data.designDocs.fetch();
- },
-
- allDocs: function(databaseName, options) {
- var docOptions = app.getParams(options);
-
- this.data.database.buildAllDocs(docOptions);
-
- if (docOptions.startkey && docOptions.startkey.indexOf('_design') > -1) {
- this.sidebar.setSelectedTab('design-docs');
- } else {
- this.sidebar.setSelectedTab('all-docs');
- }
-
- if (this.viewEditor) { this.viewEditor.remove(); }
-
- this.toolsView = this.setView("#dashboard-upper-menu", new Documents.Views.JumpToDoc({
- database: this.data.database,
- collection: this.data.database.allDocs
- }));
-
- this.setView("#dashboard-upper-content", new Documents.Views.AllDocsLayout({
- database: this.data.database,
- collection: this.data.database.allDocs,
- params: docOptions
- }));
-
- this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
- collection: this.data.database.allDocs
- }));
-
- this.crumbs = [
- {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)}
- ];
-
- this.apiUrl = [this.data.database.allDocs.url("apiurl"), this.data.database.allDocs.documentation() ];
- },
-
- viewFn: function (databaseName, ddoc, view) {
- var params = app.getParams(),
- decodeDdoc = decodeURIComponent(ddoc);
-
- view = view.replace(/\?.*$/,'');
-
- this.data.indexedDocs = new Documents.IndexCollection(null, {
- database: this.data.database,
- design: decodeDdoc,
- view: view,
- params: params
- });
-
- var ddocInfo = {
- id: "_design/" + decodeDdoc,
- currView: view,
- designDocs: this.data.designDocs
- };
-
- this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
- model: this.data.database,
- ddocs: this.data.designDocs,
- viewName: view,
- params: params,
- newView: false,
- database: this.data.database,
- ddocInfo: ddocInfo
- }));
-
- if (this.toolsView) { this.toolsView.remove(); }
-
- this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
- database: this.data.database,
- collection: this.data.indexedDocs,
- nestedView: Documents.Views.Row,
- viewList: true,
- ddocInfo: ddocInfo
- }));
-
- this.sidebar.setSelectedTab(app.mixins.removeSpecialCharacters(ddoc) + '_' + app.mixins.removeSpecialCharacters(view));
-
- this.crumbs = function () {
- return [
- {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
- ];
- };
-
- this.apiUrl = [this.data.indexedDocs.url("apiurl"), "docs"];
- },
-
- newViewEditor: function () {
- var params = app.getParams();
-
- if (this.toolsView) {
- this.toolsView.remove();
- }
-
- this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
- ddocs: this.data.designDocs,
- params: params,
- database: this.data.database,
- newView: true
- }));
-
- this.sidebar.setSelectedTab('new-view');
- this.crumbs = function () {
- return [
- {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
- ];
- };
- },
-
- updateAllDocsFromView: function (event) {
- var view = event.view,
- docOptions = app.getParams(),
- ddoc = event.ddoc;
-
- this.documentsView && this.documentsView.remove();
-
- if (event.allDocs) {
- this.data.database.buildAllDocs(docOptions);
- this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
- collection: this.data.database.allDocs
- }));
- return;
- }
-
- this.data.indexedDocs = new Documents.IndexCollection(null, {
- database: this.data.database,
- design: ddoc,
- view: view,
- params: app.getParams()
- });
-
- this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
- database: this.data.database,
- collection: this.data.indexedDocs,
- nestedView: Documents.Views.Row,
- viewList: true
- }));
- },
-
- updateAllDocsFromPreview: function (event) {
- var view = event.view,
- rows = event.rows,
- ddoc = event.ddoc;
-
- this.data.indexedDocs = new Documents.PouchIndexCollection(null, {
- database: this.data.database,
- design: ddoc,
- view: view,
- rows: rows
- });
-
- this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
- database: this.data.database,
- collection: this.data.indexedDocs,
- nestedView: Documents.Views.Row,
- viewList: true
- }));
- },
-
- paginate: function (direction) {
- _.extend(this.documentsView.collection.params, app.getParams());
- this.documentsView.forceRender();
- if (direction === 'next') {
- this.documentsView.collection.skipFirstItem = true;
- } else {
- this.documentsView.collection.skipFirstItem = false;
- }
- },
-
- reloadDesignDocs: function (event) {
- this.sidebar.forceRender();
-
- if (event && event.selectedTab) {
- this.sidebar.setSelectedTab(event.selectedTab);
- }
- }
-
- });
-
- var ChangesRouteObject = FauxtonAPI.RouteObject.extend({
- layout: "with_tabs",
- selectedHeader: "Databases",
- crumbs: function () {
- return [
- {"name": this.database.id, "link": Databases.databaseUrl(this.database)},
- {"name": "_changes", "link": "/_changes"}
- ];
- },
-
- routes: {
- "database/:database/_changes(:params)": "changes"
- },
-
- initialize: function (route, masterLayout, options) {
- this.databaseName = options[0];
- this.database = new Databases.Model({id: this.databaseName});
-
- var docOptions = app.getParams();
-
- this.database.buildChanges(docOptions);
-
- this.setView("#tabs", new Documents.Views.Tabs({
- collection: this.designDocs,
- database: this.database,
- active_id: 'changes'
- }));
- },
-
- changes: function (event) {
- this.setView("#dashboard-content", new Documents.Views.Changes({
- model: this.database
- }));
- },
-
- apiUrl: function() {
- return [this.database.url("apiurl"), this.database.documentation()];
- }
-
- });
-
- Documents.RouteObjects = [DocEditorRouteObject, NewDocEditorRouteObject, DocumentsRouteObject, ChangesRouteObject];
-
- return Documents;
-});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/89810cce/src/fauxton/app/modules/documents/tests/resourcesSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/tests/resourcesSpec.js b/src/fauxton/app/modules/documents/tests/resourcesSpec.js
deleted file mode 100644
index e848221..0000000
--- a/src/fauxton/app/modules/documents/tests/resourcesSpec.js
+++ /dev/null
@@ -1,84 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-define([
- 'modules/documents/resources',
- 'testUtils'
-], function (Models, testUtils) {
- var assert = testUtils.assert;
-
- describe('IndexCollection', function () {
- var collection;
- beforeEach(function () {
- collection = new Models.IndexCollection([{
- id:'myId1',
- doc: 'num1'
- },
- {
- id:'myId2',
- doc: 'num2'
- }], {
- database: {id: 'databaseId', safeID: function () { return this.id; }},
- design: '_design/myDoc'
- });
-
- });
-
- it('Should return urlNext', function () {
- var url = collection.urlNextPage(20);
-
- assert.equal(url, 'database/databaseId/_design/myDoc/_view/?limit=21&reduce=false&startkey_docid=myId2&startkey=');
-
- });
-
- it('Should return urlPrevious', function () {
- var url = collection.urlPreviousPage(20, {limit: 21, reduce: false, startkey_docid: "myId1",startkey:"myId1"} );
-
- assert.equal(url, 'database/databaseId/_design/myDoc/_view/?limit=20&reduce=false&startkey_docid=myId1&startkey=myId1');
-
- });
-
- });
-
- describe('AllDocs', function () {
- var collection;
- beforeEach(function () {
- collection = new Models.AllDocs([{
- _id:'myId1',
- doc: 'num1'
- },
- {
- _id:'myId2',
- doc: 'num2'
- }], {
- database: {id: 'databaseId', safeID: function () { return this.id; }},
- params: {limit: 20}
- });
-
- });
-
- it('Should return urlNext', function () {
- var url = collection.urlNextPage(20);
-
- assert.equal(url, 'database/databaseId/_all_docs?limit=21&startkey_docid=%22myId2%22&startkey=%22myId2%22');
-
- });
-
- it('Should return urlPrevious', function () {
- var url = collection.urlPreviousPage(20, {limit: 21, startkey_docid: "myId1",startkey:"myId1"} );
- assert.equal(url, 'database/databaseId/_all_docs?limit=20&startkey_docid=myId1&startkey=myId1');
- });
-
-
- });
-
-});
-
http://git-wip-us.apache.org/repos/asf/couchdb/blob/89810cce/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js
deleted file mode 100644
index 59aba01..0000000
--- a/src/fauxton/app/modules/documents/views.js
+++ /dev/null
@@ -1,1855 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-define([
- "app",
-
- "api",
- "modules/fauxton/components",
-
- "modules/documents/resources",
- "modules/databases/resources",
- "modules/pouchdb/base",
-
- // Libs
- "resizeColumns",
-
- // Plugins
- "plugins/prettify"
-
-],
-
-function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColumns) {
- var Views = {};
- Views.Tabs = FauxtonAPI.View.extend({
- template: "templates/documents/tabs",
- initialize: function(options){
- this.collection = options.collection;
- this.database = options.database;
- this.active_id = options.active_id;
- },
-
- events: {
- "click #delete-database": "delete_database"
- },
-
- serialize: function () {
- return {
- // TODO make this not hard coded here
- changes_url: '#' + this.database.url('changes'),
- db_url: '#' + this.database.url('index') + '?limit=' + Databases.DocLimit,
- };
- },
-
- beforeRender: function(manage) {
- this.insertView("#search", new Views.SearchBox({
- collection: this.collection,
- database: this.database.id
- }));
- },
-
- afterRender: function () {
- if (this.active_id) {
- this.$('.active').removeClass('active');
- this.$('#'+this.active_id).addClass('active');
- }
- },
-
- delete_database: function (event) {
- event.preventDefault();
-
- var result = confirm("Are you sure you want to delete this database?");
-
- if (!result) { return; }
- FauxtonAPI.addNotification({
- msg: "Deleting your database...",
- type: "error"
- });
- return this.database.destroy().done(function () {
- app.router.navigate('#/_all_dbs', {trigger: true});
- });
- }
- });
-
- Views.SearchBox = FauxtonAPI.View.extend({
- template: "templates/documents/search",
- tagName: "form",
- initialize: function(options){
- this.collection = options.collection;
- this.database = options.database;
- },
- afterRender: function(){
- var collection = this.collection;
- var form = this.$el;
- var searchbox = form.find("input#searchbox");
- var database = this.database;
-
- form.submit(function(evt){
- evt.preventDefault();
- var viewname = form.find("input#view").val().split('/');
- var url = "#database/" + database + "/_design/";
- url += viewname[0] + "/_view/" + viewname[1];
- if (searchbox.val() !== ""){
- // TODO: this'll need to work when val() is a number etc.
- url += '?startkey="' + searchbox.val() + '"';
- }
- FauxtonAPI.navigate(url);
- });
-
- searchbox.typeahead({
- source: function(query, process) {
- // TODO: include _all_docs and view keys somehow
- var views = _.map(collection.pluck('doc'), function(d){
- return _.map(_.keys(d.views), function(view){
- return d._id.split('/')[1] + "/" + view;
- });
- });
- return _.flatten(views);
- },
- minLength: 3,
- updater: function(item){
- // TODO: some way to return the original search box
- this.$element.removeClass('span12');
- this.$element.addClass('span6');
- this.$element.attr('placeholder', 'Search by view key');
- $('<span class="add-on span6">' + item +'</span>').insertBefore(this.$element);
- $('<input type="hidden" id="view" value="' + item +'"/>').insertBefore(this.$element);
- // Remove the type ahead for now
- $('.typehead').unbind();
- }
- });
- }
- });
-
- Views.UploadModal = FauxtonAPI.View.extend({
- template: "templates/documents/upload_modal",
-
- disableLoader: true,
-
- initialize: function (options) {
- _.bindAll(this);
- },
-
- events: {
- "click a#upload-btn": "uploadFile"
- },
-
- uploadFile: function (event) {
- event.preventDefault();
-
- var docRev = this.model.get('_rev'),
- that = this,
- $form = this.$('#file-upload');
-
- if (!docRev) {
- return this.set_error_msg('The document needs to be saved before adding an attachment.');
- }
-
- if ($('input[type="file"]')[0].files.length === 0) {
- return this.set_error_msg('Selected a file to be uploaded.');
- }
-
- this.$('#_rev').val(docRev);
-
- $form.ajaxSubmit({
- url: this.model.url(),
- type: 'POST',
- beforeSend: this.beforeSend,
- uploadProgress: this.uploadProgress,
- success: this.success,
- error: function (resp) {
- console.log('ERR on upload', resp);
- return that.set_error_msg('Could not upload document: ' + JSON.parse(resp.responseText).reason);
- }
- });
- },
-
- success: function (resp) {
- var hideModal = this.hideModal,
- $form = this.$('#file-upload');
-
- FauxtonAPI.triggerRouteEvent('reRenderDoc');
- //slight delay to make this transistion a little more fluid and less jumpy
- setTimeout(function () {
- $form.clearForm();
- hideModal();
- $('.modal-backdrop').remove();
- }, 1000);
- },
-
- uploadProgress: function(event, position, total, percentComplete) {
- this.$('.bar').css({width: percentComplete + '%'});
- },
-
- beforeSend: function () {
- this.$('.progress').removeClass('hide');
- },
-
- showModal: function () {
- this.$('.bar').css({width: '0%'});
- this.$('.progress').addClass('hide');
- this.clear_error_msg();
- this.$('.modal').modal();
- // hack to get modal visible
- $('.modal-backdrop').css('z-index',1025);
- },
-
- hideModal: function () {
- this.$('.modal').modal('hide');
- },
-
- set_error_msg: function (msg) {
- var text;
- if (typeof(msg) == 'string') {
- text = msg;
- } else {
- text = JSON.parse(msg.responseText).reason;
- }
- this.$('#modal-error').text(text).removeClass('hide');
- },
-
- clear_error_msg: function () {
- this.$('#modal-error').text(' ').addClass('hide');
- },
-
- serialize: function () {
- return this.model.toJSON();
- }
- });
-
- Views.DuplicateDocModal = FauxtonAPI.View.extend({
- template: "templates/documents/duplicate_doc_modal",
-
- initialize: function () {
- _.bindAll(this);
- },
-
- events: {
- "click #duplicate-btn":"duplicate"
-
- },
-
- duplicate: function (event) {
- event.preventDefault();
- var newId = this.$('#dup-id').val(),
- encodedID = app.mixins.safeURLName(newId);
-
- this.hideModal();
- FauxtonAPI.triggerRouteEvent('duplicateDoc', encodedID);
- },
-
- _showModal: function () {
- this.$('.bar').css({width: '0%'});
- this.$('.progress').addClass('hide');
- this.clear_error_msg();
- this.$('.modal').modal();
- // hack to get modal visible
- $('.modal-backdrop').css('z-index',1025);
- },
-
- showModal: function () {
- var showModal = this._showModal,
- setDefaultIdValue = this.setDefaultIdValue,
- uuid = new FauxtonAPI.UUID();
-
- uuid.fetch().then(function () {
- setDefaultIdValue(uuid.next());
- showModal();
- });
- },
-
- setDefaultIdValue: function (id) {
- this.$('#dup-id').val(id);
- },
-
- hideModal: function () {
- this.$('.modal').modal('hide');
- },
-
- set_error_msg: function (msg) {
- var text;
- if (typeof(msg) == 'string') {
- text = msg;
- } else {
- text = JSON.parse(msg.responseText).reason;
- }
- this.$('#modal-error').text(text).removeClass('hide');
- },
-
- clear_error_msg: function () {
- this.$('#modal-error').text(' ').addClass('hide');
- },
-
- serialize: function () {
- return this.model.toJSON();
- }
-
- });
-
- Views.FieldEditorTabs = FauxtonAPI.View.extend({
- template: "templates/documents/doc_field_editor_tabs",
- disableLoader: true,
- initialize: function(options) {
- this.selected = options.selected;
- },
-
- events: {
- },
- updateSelected: function (selected) {
- this.selected = selected;
- this.$('.active').removeClass('active');
- this.$('#'+this.selected).addClass('active');
- },
-
- serialize: function() {
- var selected = this.selected;
- return {
- doc: this.model,
- isNewDoc: this.model.isNewDoc(),
- isSelectedClass: function(item) {
- return item && item === selected ? "active" : "";
- }
- };
- },
-
- establish: function() {
- return [this.model.fetch()];
- }
- });
-
- Views.Document = FauxtonAPI.View.extend({
- template: "templates/documents/all_docs_item",
- tagName: "tr",
- className: "all-docs-item",
-
- events: {
- "click button.delete": "destroy",
- "dblclick pre.prettyprint": "edit"
- },
-
- attributes: function() {
- return {
- "data-id": this.model.id
- };
- },
-
- serialize: function() {
- return {
- doc: this.model
- };
- },
-
- establish: function() {
- return [this.model.fetch()];
- },
-
- edit: function(event) {
- event.preventDefault();
- FauxtonAPI.navigate("#" + this.model.url('app'));
- },
-
- destroy: function(event) {
- event.preventDefault();
- var that = this;
-
- if (!window.confirm("Are you sure you want to delete this doc?")) {
- return false;
- }
-
- this.model.destroy().then(function(resp) {
- FauxtonAPI.addNotification({
- msg: "Succesfully destroyed your doc"
- });
- that.$el.fadeOut(function () {
- that.remove();
- });
-
- that.model.collection.remove(that.model.id);
- if (!!that.model.id.match('_design')) {
- FauxtonAPI.triggerRouteEvent('reloadDesignDocs');
- }
- }, function(resp) {
- FauxtonAPI.addNotification({
- msg: "Failed to destroy your doc!",
- type: "error"
- });
- });
- }
- });
-
- Views.Row = FauxtonAPI.View.extend({
- template: "templates/documents/index_row_docular",
- tagName: "tr",
-
- events: {
- "click button.delete": "destroy"
- },
-
- destroy: function (event) {
- event.preventDefault();
-
- window.alert('Cannot delete a document generated from a view.');
- },
-
- serialize: function() {
- return {
- doc: this.model
- };
- }
- });
-
- Views.IndexItem = FauxtonAPI.View.extend({
- template: "templates/documents/index_menu_item",
- tagName: "li",
-
- initialize: function(options){
- this.index = options.index;
- this.ddoc = options.ddoc;
- this.database = options.database;
- this.selected = !! options.selected;
- },
-
- serialize: function() {
- return {
- index: this.index,
- ddoc: this.ddoc,
- database: this.database,
- index_clean: app.mixins.removeSpecialCharacters(this.index),
- ddoc_clean: app.mixins.removeSpecialCharacters(this.ddoc),
- index_encoded: app.mixins.safeURLName(this.index),
- ddoc_encoded: app.mixins.safeURLName(this.ddoc),
- database_encoded: app.mixins.safeURLName(this.database),
- selected: this.selected
- };
- },
-
- afterRender: function() {
- if (this.selected) {
- $("#sidenav ul.nav-list li").removeClass("active");
- this.$el.addClass("active");
- }
- }
- });
-
- Views.AllDocsNumber = FauxtonAPI.View.extend({
- template: "templates/documents/all_docs_number",
-
- initialize: function (options) {
- this.newView = options.newView || false;
- this.showNumbers = options.showNumbers;
- this.pagination = options.pagination;
-
- this.listenTo(this.collection, 'totalRows:decrement', this.render);
- },
-
- serialize: function () {
- var totalRows = 0,
- recordStart = 0,
- updateSeq = false,
- pageStart = 0,
- pageEnd = 20;
-
- if (!this.newView) {
- totalRows = this.collection.totalRows();
- updateSeq = this.collection.updateSeq();
- }
-
- recordStart = this.collection.recordStart();
- if (this.pagination) {
- pageStart = this.pagination.pageStart();
- pageEnd = this.pagination.pageEnd();
- }
-
- return {
- database: app.mixins.safeURLName(this.collection.database.id),
- updateSeq: updateSeq,
- offset: recordStart,
- totalRows: totalRows,
- showNumbers: this.showNumbers,
- numModels: this.collection.models.length + recordStart - 1,
- pageStart: pageStart,
- pageEnd: pageEnd
- };
- }
-
- });
-
- Views.AllDocsLayout = FauxtonAPI.View.extend({
- template: "templates/documents/all_docs_layout",
- className: "row",
-
- initialize: function (options) {
- this.database = options.database;
- this.params = options.params;
- },
-
- events: {
- 'click #toggle-query': "toggleQuery"
- },
-
- toggleQuery: function (event) {
- $('#dashboard-content').scrollTop(0);
- this.$('#query').toggle('fast');
- },
-
- beforeRender: function () {
- this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({
- updateViewFn: this.updateAllDocs,
- previewFn: this.previewView,
- hasReduce: false,
- showPreview: false,
- database: this.database
- }));
-
- this.$('#query').hide();
- },
-
- afterRender: function () {
- if (this.params) {
- this.advancedOptions.updateFromParams(this.params);
- }
-
- },
-
- updateAllDocs: function (event, paramInfo) {
- event.preventDefault();
-
- var errorParams = paramInfo.errorParams,
- params = paramInfo.params;
-
- if (_.any(errorParams)) {
- _.map(errorParams, function(param) {
-
- // TODO: Where to add this error?
- // bootstrap wants the error on a control-group div, but we're not using that
- //$('form.view-query-update input[name='+param+'], form.view-query-update select[name='+param+']').addClass('error');
- return FauxtonAPI.addNotification({
- msg: "JSON Parse Error on field: "+param.name,
- type: "error",
- selector: ".advanced-options .errors-container"
- });
- });
- FauxtonAPI.addNotification({
- msg: "Make sure that strings are properly quoted and any other values are valid JSON structures",
- type: "warning",
- selector: ".advanced-options .errors-container"
- });
-
- return false;
- }
-
- var fragment = window.location.hash.replace(/\?.*$/, '');
- fragment = fragment + '?' + $.param(params);
- FauxtonAPI.navigate(fragment, {trigger: false});
-
- FauxtonAPI.triggerRouteEvent('updateAllDocs', {allDocs: true});
- },
-
- previewView: function (event) {
- event.preventDefault();
- }
-
- });
-
- // TODO: Rename to reflect that this is a list of rows or documents
- Views.AllDocsList = FauxtonAPI.View.extend({
- template: "templates/documents/all_docs_list",
- events: {
- "click button.all": "selectAll",
- "click button.bulk-delete": "bulkDelete",
- "click #collapse": "collapse",
- "change .row-select":"toggleTrash"
- },
-
- toggleTrash: function () {
- if (this.$('.row-select:checked').length > 0) {
- this.$('.bulk-delete').removeClass('disabled');
- } else {
- this.$('.bulk-delete').addClass('disabled');
- }
- },
-
- initialize: function(options){
- this.nestedView = options.nestedView || Views.Document;
- this.rows = {};
- this.viewList = !! options.viewList;
- this.database = options.database;
- if (options.ddocInfo) {
- this.designDocs = options.ddocInfo.designDocs;
- this.ddocID = options.ddocInfo.id;
- }
- this.newView = options.newView || false;
- this.expandDocs = true;
- },
-
- establish: function() {
- if (this.newView) { return null; }
-
- return this.collection.fetch({reset: true}).fail(function() {
- // TODO: handle error requests that slip through
- // This should just throw a notification, not break the page
- console.log("ERROR: ", arguments);
- });
- },
-
- selectAll: function(evt){
- $('.all-docs').find("input:checkbox").prop('checked', !$(evt.target).hasClass('active')).trigger('change');
- },
-
- serialize: function() {
- var requestDuration = false;
-
- if (this.collection.requestDurationInString) {
- requestDuration = this.collection.requestDurationInString();
- }
-
- return {
- viewList: this.viewList,
- requestDuration: requestDuration,
- expandDocs: this.expandDocs
- };
- },
-
- collapse: function (event) {
- event.preventDefault();
-
- if (this.expandDocs) {
- this.expandDocs = false;
- } else {
- this.expandDocs = true;
- }
-
- this.render();
- },
-
- /*
- * TODO: this should be reconsidered
- * This currently performs delete operations on the model level,
- * when we could be using bulk docs with _deleted = true. Using
- * individual models is cleaner from a backbone standpoint, but
- * not from the couchdb api.
- * Also, the delete method is naive and leaves the body intact,
- * when we should switch the doc to only having id/rev/deleted.
- */
- bulkDelete: function() {
- var that = this;
- // yuck, data binding ftw?
- var eles = this.$el.find("input.row-select:checked")
- .parents("tr.all-docs-item")
- .map(function(e) { return $(this).attr("data-id"); })
- .get();
-
- if (eles.length === 0 || !window.confirm("Are you sure you want to delete these " + eles.length + " docs?")) {
- return false;
- }
-
- _.each(eles, function(ele) {
- var model = this.collection.get(ele);
-
- model.destroy().then(function(resp) {
- that.rows[ele].$el.fadeOut(function () {
- $(this).remove();
- });
-
- model.collection.remove(model.id);
- if (!!model.id.match('_design')) {
- FauxtonAPI.triggerRouteEvent('reloadDesignDocs');
- }
- that.$('.bulk-delete').addClass('disabled');
- }, function(resp) {
- FauxtonAPI.addNotification({
- msg: "Failed to destroy your doc!",
- type: "error"
- });
- });
- }, this);
- },
-
- addPagination: function () {
- var collection = this.collection;
- var perPage = function () {
- if (collection.params.limit && collection.skipFirstItem) {
- return parseInt(collection.params.limit, 10) - 1;
- } else if (collection.params.limit) {
- return parseInt(collection.params.limit, 10);
- }
-
- return 20;
- };
-
- this.pagination = new Components.IndexPagination({
- collection: this.collection,
- scrollToSelector: '#dashboard-content',
- previousUrlfn: function () {
- return collection.urlPreviousPage(perPage(), this.previousParams.pop());
- },
- canShowPreviousfn: function () {
- if (this.previousParams.length === 0) {
- return false;
- }
-
- return true;
- },
- canShowNextfn: function () {
- if (collection.length < (perPage() -1)) {
- return false;
- }
-
- return true;
- },
-
- nextUrlfn: function () {
- return collection.urlNextPage(perPage());
- }
- });
- },
-
- cleanup: function () {
- //if (!this.pagination) { return; }
- this.pagination.remove();
- //this.pagination = null;
- this.allDocsNumber.remove();
- _.each(this.rows, function (row) {row.remove();});
- },
-
- beforeRender: function() {
- var showNumbers = true;
-
- if (!this.pagination) {
- this.addPagination();
- }
-
- this.insertView('#documents-pagination', this.pagination);
-
- if (this.designDocs || this.collection.idxType === '_view' || this.collection.params.startkey === '"_design"') {
- showNumbers = false;
- }
-
- this.allDocsNumber = this.setView('#item-numbers', new Views.AllDocsNumber({
- collection: this.collection,
- newView: this.newView,
- showNumbers: showNumbers,
- pagination: this.pagination
- }));
-
- var docs = this.expandDocs ? this.collection : this.collection.simple();
-
- docs.each(function(doc) {
- this.rows[doc.id] = this.insertView("table.all-docs tbody", new this.nestedView({
- model: doc
- }));
- }, this);
- },
-
- afterRender: function(){
- prettyPrint();
- }
- });
-
- Views.Doc = FauxtonAPI.View.extend({
- template: "templates/documents/doc",
- events: {
- "click button.save-doc": "saveDoc",
- "click button.delete": "destroy",
- "click button.duplicate": "duplicate",
- "click button.upload": "upload",
- "click button.cancel-button": "goback"
- },
- disableLoader: true,
- initialize: function (options) {
- this.database = options.database;
- _.bindAll(this);
- },
- goback: function(){
- FauxtonAPI.navigate(this.database.url("index") + "?limit=100");
- },
- destroy: function(event) {
- if (this.model.isNewDoc()) {
- FauxtonAPI.addNotification({
- msg: 'This document has not been saved yet.',
- type: 'warning'
- });
- return;
- }
-
- if (!window.confirm("Are you sure you want to delete this doc?")) {
- return false;
- }
-
- var database = this.model.database;
-
- this.model.destroy().then(function(resp) {
- FauxtonAPI.addNotification({
- msg: "Succesfully destroyed your doc"
- });
- FauxtonAPI.navigate(database.url("index"));
- }, function(resp) {
- FauxtonAPI.addNotification({
- msg: "Failed to destroy your doc!",
- type: "error"
- });
- });
- },
-
- beforeRender: function () {
- this.uploadModal = this.setView('#upload-modal', new Views.UploadModal({model: this.model}));
- this.uploadModal.render();
-
- this.duplicateModal = this.setView('#duplicate-modal', new Views.DuplicateDocModal({model: this.model}));
- this.duplicateModal.render();
- },
-
- upload: function (event) {
- event.preventDefault();
- if (this.model.isNewDoc()) {
- FauxtonAPI.addNotification({
- msg: 'Please save the document before uploading an attachment.',
- type: 'warning'
- });
- return;
- }
- this.uploadModal.showModal();
- },
-
- duplicate: function(event) {
- if (this.model.isNewDoc()) {
- FauxtonAPI.addNotification({
- msg: 'Please save the document before duplicating it.',
- type: 'warning'
- });
- return;
- }
- event.preventDefault();
- this.duplicateModal.showModal();
- },
-
- 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());
- }
- },
-
- establish: function() {
- var promise = this.model.fetch(),
- databaseId = this.database.safeID(),
- deferred = $.Deferred(),
- that = this;
-
- promise.then(function () {
- deferred.resolve();
- }, function (xhr, reason, msg) {
- if (xhr.status === 404) {
- FauxtonAPI.addNotification({
- msg: 'The document does not exist',
- type: 'error',
- clear: true
- });
- that.goback();
- }
- deferred.reject();
- });
-
- return deferred;
- },
-
- saveDoc: function(event) {
- var json, notification,
- that = this,
- editor = this.editor,
- validDoc = this.getDocFromEditor();
-
- if (validDoc) {
- this.getDocFromEditor();
-
- notification = FauxtonAPI.addNotification({msg: "Saving document."});
-
- this.model.save().then(function () {
- editor.editSaved();
- FauxtonAPI.navigate('/database/' + that.database.safeID() + '/' + that.model.id);
- }).fail(function(xhr) {
-
- var responseText = JSON.parse(xhr.responseText).reason;
- notification = FauxtonAPI.addNotification({
- msg: "Save failed: " + responseText,
- type: "error",
- clear: true,
- selector: "#doc .errors-container"
- });
- });
- } else if(this.model.validationError && this.model.validationError === 'Cannot change a documents id.') {
- notification = FauxtonAPI.addNotification({
- msg: "Cannot save: " + 'Cannot change a documents _id, try Duplicate doc instead!',
- type: "error",
- selector: "#doc .errors-container"
- });
- delete this.model.validationError;
- } else {
- notification = FauxtonAPI.addNotification({
- msg: "Please fix the JSON errors and try again.",
- type: "error",
- selector: "#doc .errors-container"
- });
- }
- },
-
- getDocFromEditor: function () {
- if (!this.hasValidCode()) {
- return false;
- }
-
- json = JSON.parse(this.editor.getValue());
-
- this.model.clear().set(json, {validate: true});
- if (this.model.validationError) {
- return false;
- }
-
- return this.model;
- },
-
- hasValidCode: function() {
- var errors = this.editor.getAnnotations();
- return errors.length === 0;
- },
-
- serialize: function() {
- return {
- doc: this.model,
- attachments: this.getAttachments()
- };
- },
-
- getAttachments: function () {
- var attachments = this.model.get('_attachments');
-
- if (!attachments) { return false; }
-
- return _.map(attachments, function (att, key) {
- return {
- fileName: key,
- size: att.length,
- contentType: att.content_type,
- url: this.model.url() + '/' + key
- };
- }, this);
- },
-
- afterRender: function() {
- var saveDoc = this.saveDoc;
-
- this.editor = new Components.Editor({
- editorId: "editor-container",
- commands: [{
- name: 'save',
- bindKey: {win: 'Ctrl-S', mac: 'Ctrl-S'},
- exec: function(editor) {
- saveDoc();
- },
- readOnly: true // false if this command should not apply in readOnly mode
- }]
- });
- this.editor.render();
- this.model.on("sync", this.updateValues, this);
- },
-
- cleanup: function () {
- if (this.editor) this.editor.remove();
- }
- });
-
- Views.DocFieldEditor = FauxtonAPI.View.extend({
- template: "templates/documents/doc_field_editor",
- disableLoader: true,
- events: {
- "click button.save": "saveDoc"
- },
-
- saveDoc: function(event) {
- FauxtonAPI.addNotification({
- type: "warning",
- msg: "Save functionality coming soon."
- });
- },
-
- serialize: function() {
- return {
- doc: this.getModelWithoutAttachments(),
- attachments: this.getAttachments()
- };
- },
-
- getModelWithoutAttachments: function() {
- var model = this.model.toJSON();
- delete model._attachments;
- return model;
- },
-
- getAttachments: function () {
- var attachments = this.model.get('_attachments');
-
- if (!attachments) { return []; }
-
- return _.map(attachments, function (att, key) {
- return {
- fileName: key,
- size: att.length,
- contentType: att.content_type,
- url: this.model.url() + '/' + key
- };
- }, this);
- },
-
- establish: function() {
- return [this.model.fetch()];
- }
- });
-
- Views.AdvancedOptions = FauxtonAPI.View.extend({
- template: "templates/documents/advanced_options",
- className: "advanced-options well",
-
- initialize: function (options) {
- this.database = options.database;
- this.ddocName = options.ddocName;
- this.viewName = options.viewName;
- this.updateViewFn = options.updateViewFn;
- this.previewFn = options.previewFn;
- //this.hadReduce = options.hasReduce || true;
-
- if (typeof(options.hasReduce) === 'undefined') {
- this.hasReduce = true;
- } else {
- this.hasReduce = options.hasReduce;
- }
-
- if (typeof(options.showPreview) === 'undefined') {
- this.showPreview = true;
- } else {
- this.showPreview = options.showPreview;
- }
- },
-
- events: {
- "change form.view-query-update input": "updateFilters",
- "change form.view-query-update select": "updateFilters",
- "submit form.view-query-update": "updateView",
- "click button.preview": "previewView"
- },
-
- beforeRender: function () {
- if (this.viewName && this.ddocName) {
- var buttonViews = FauxtonAPI.getExtensions('advancedOptions:ViewButton');
- _.each(buttonViews, function (view) {
- this.insertView('#button-options', view);
- view.update(this.database, this.ddocName, this.viewName);
- }, this);
- }
- },
-
- renderOnUpdatehasReduce: function (hasReduce) {
- this.hasReduce = hasReduce;
- this.render();
- },
-
- queryParams: function () {
- var $form = this.$(".view-query-update");
- // Ignore params without a value
- var params = _.filter($form.serializeArray(), function(param) {
- return param.value;
- });
-
- // Validate *key* params to ensure they're valid JSON
- var keyParams = ["key","keys","startkey","endkey"];
- var errorParams = _.filter(params, function(param) {
- if (_.contains(keyParams, param.name)) {
- try {
- JSON.parse(param.value);
- return false;
- } catch(e) {
- return true;
- }
- } else {
- return false;
- }
- });
-
- return {params: params, errorParams: errorParams};
- },
-
- updateFilters: function(event) {
- event.preventDefault();
- var $ele = $(event.currentTarget);
- var name = $ele.attr('name');
- this.updateFiltersFor(name, $ele);
- },
-
- updateFiltersFor: function(name, $ele) {
- var $form = $ele.parents("form.view-query-update:first");
- switch (name) {
- // Reduce constraints
- // - Can't include_docs for reduce=true
- // - can't include group_level for reduce=false
- case "reduce":
- if ($ele.prop('checked') === true) {
- if ($form.find("input[name=include_docs]").prop("checked") === true) {
- $form.find("input[name=include_docs]").prop("checked", false);
- var notification = FauxtonAPI.addNotification({
- msg: "include_docs has been disabled as you cannot include docs on a reduced view",
- type: "warn",
- selector: ".view.show .all-docs-list.errors-container"
- });
- }
- $form.find("input[name=include_docs]").prop("disabled", true);
- $form.find("select[name=group_level]").prop("disabled", false);
- } else {
- $form.find("select[name=group_level]").prop("disabled", true);
- $form.find("input[name=include_docs]").prop("disabled", false);
- }
- break;
- case "include_docs":
- break;
- }
- },
-
- updateFromParams: function (params) {
- var $form = this.$el.find("form.view-query-update");
- _.each(params, function(val, key) {
- var $ele;
- switch (key) {
- case "limit":
- case "group_level":
- $form.find("select[name='"+key+"']").val(val);
- break;
- case "include_docs":
- case "stale":
- case "descending":
- case "inclusive_end":
- $form.find("input[name='"+key+"']").prop('checked', true);
- break;
- case "reduce":
- $ele = $form.find("input[name='"+key+"']");
- if (val == "true") {
- $ele.prop('checked', true);
- }
- this.updateFiltersFor(key, $ele);
- break;
- default:
- $form.find("input[name='"+key+"']").val(val);
- break;
- }
- }, this);
- },
-
- updateView: function (event) {
- this.updateViewFn(event, this.queryParams());
- },
-
- previewView: function (event) {
- this.previewFn(event, this.queryParams());
- },
-
- serialize: function () {
- return {
- hasReduce: this.hasReduce,
- showPreview: this.showPreview
- };
- }
- });
-
- Views.DesignDocSelector = FauxtonAPI.View.extend({
- template: "templates/documents/design_doc_selector",
-
- events: {
- "change select#ddoc": "updateDesignDoc"
- },
-
- initialize: function (options) {
- this.ddocName = options.ddocName;
- this.database = options.database;
- this.listenTo(this.collection, 'add', this.ddocAdded);
- this.DocModel = options.DocModel || Documents.Doc;
- },
-
- ddocAdded: function (ddoc) {
- this.ddocName = ddoc.id;
- this.render();
- },
-
- serialize: function () {
- return {
- ddocName: this.ddocName,
- ddocs: this.collection
- };
- },
-
- updateDesignDoc: function () {
- if (this.newDesignDoc()) {
- this.$('#new-ddoc-section').show();
- } else {
- this.$('#new-ddoc-section').hide();
- }
- },
-
- newDesignDoc: function () {
-
- return this.$('#ddoc').val() === 'new-doc';
- },
-
- newDocValidation: function(){
- return this.newDesignDoc() && this.$('#new-ddoc').val()==="";
- },
- getCurrentDesignDoc: function () {
- if (this.newDesignDoc()) {
- var doc = {
- _id: '_design/' + this.$('#new-ddoc').val(),
- views: {},
- language: "javascript"
- };
- var ddoc = new this.DocModel(doc, {database: this.database});
- //this.collection.add(ddoc);
- return ddoc;
- } else if ( !this.newDesignDoc() ) {
- var ddocName = this.$('#ddoc').val();
- return this.collection.find(function (ddoc) {
- return ddoc.id === ddocName;
- }).dDocModel();
- }
- }
- });
-
- Views.ViewEditor = FauxtonAPI.View.extend({
- template: "templates/documents/view_editor",
- builtinReduces: ['_sum', '_count', '_stats'],
-
- events: {
- "click button.save": "saveView",
- "click button.delete": "deleteView",
- "change select#reduce-function-selector": "updateReduce",
- "click button.preview": "previewView",
- "click #db-views-tabs-nav": 'toggleIndexNav'
- },
-
- 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;
- 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);
- },
-
- establish: function () {
- if (this.ddocInfo) {
- 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();
- }
- },
-
- deleteView: function (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 json, notification,
- that = this;
-
- if (event) { event.preventDefault();}
-
- $('#dashboard-content').scrollTop(0); //scroll up
-
- 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.viewName = viewName;
-
- notification = FauxtonAPI.addNotification({
- msg: "Saving document.",
- selector: "#define-view .errors-container",
- clear: true
- });
-
- ddoc.setDdocView(viewName, mapVal, reduceVal);
-
- ddoc.save().then(function () {
- that.ddocs.add(ddoc);
-
- that.mapEditor.editSaved();
- that.reduceEditor && that.reduceEditor.editSaved();
-
- FauxtonAPI.addNotification({
- msg: "View has been saved.",
- type: "success",
- selector: "#define-view .errors-container",
- clear: true
- });
-
- if (that.newView) {
- var fragment = '/database/' + that.database.safeID() +'/' + ddoc.safeID() + '/_view/' + app.mixins.safeURLName(viewName);
-
- FauxtonAPI.navigate(fragment, {trigger: false});
- that.newView = false;
- that.ddocID = ddoc.safeID();
- that.viewName = viewName;
- that.ddocInfo = ddoc;
- that.showIndex = true;
- that.render();
- FauxtonAPI.triggerRouteEvent('reloadDesignDocs', {
- selectedTab: app.mixins.removeSpecialCharacters(ddocName.replace(/_design\//,'')) + '_' + app.mixins.removeSpecialCharacters(viewName)
- });
- }
-
- if (that.reduceFunStr !== reduceVal) {
- that.reduceFunStr = reduceVal;
- that.advancedOptions.renderOnUpdatehasReduce(that.hasReduce());
- }
-
- FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
-
- }, function(xhr) {
- var responseText = JSON.parse(xhr.responseText).reason;
- notification = FauxtonAPI.addNotification({
- msg: "Save failed: " + responseText,
- type: "error",
- clear: true
- });
- });
- } else {
- 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",
- selector: "#define-view .errors-container",
- clear: true
- });
- }
- },
-
- updateView: function(event, paramInfo) {
- event.preventDefault();
-
- if (this.newView) { return alert('Please save this new view before querying it.'); }
-
- var errorParams = paramInfo.errorParams,
- params = paramInfo.params;
-
- if (_.any(errorParams)) {
- _.map(errorParams, function(param) {
-
- // TODO: Where to add this error?
- // bootstrap wants the error on a control-group div, but we're not using that
- //$('form.view-query-update input[name='+param+'], form.view-query-update select[name='+param+']').addClass('error');
- return FauxtonAPI.addNotification({
- msg: "JSON Parse Error on field: "+param.name,
- type: "error",
- selector: ".advanced-options .errors-container",
- clear: true
- });
- });
- FauxtonAPI.addNotification({
- msg: "Make sure that strings are properly quoted and any other values are valid JSON structures",
- type: "warning",
- selector: ".advanced-options .errors-container",
- clear: true
- });
-
- return false;
- }
-
- var fragment = window.location.hash.replace(/\?.*$/, '');
- fragment = fragment + '?' + $.param(params);
- FauxtonAPI.navigate(fragment, {trigger: false});
-
- FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
- },
-
-
- previewView: function(event, paramsInfo) {
- event.preventDefault();
- var that = this,
- mapVal = this.mapVal(),
- reduceVal = this.reduceVal(),
- paramsArr = [];
-
- if (paramsInfo && paramsInfo.params) {
- paramsArr = paramsInfo.params;
- }
-
- var params = _.reduce(paramsArr, function (params, param) {
- params[param.name] = param.value;
- return params;
- }, {reduce: false});
-
- event.preventDefault();
-
- FauxtonAPI.addNotification({
- msg: "<strong>Warning!</strong> Preview executes the Map/Reduce functions in your browser, and may behave differently from CouchDB.",
- type: "warning",
- selector: ".advanced-options .errors-container",
- fade: true
- });
-
- var promise = FauxtonAPI.Deferred();
-
- if (!this.database.allDocs) {
- this.database.buildAllDocs({limit: Databases.DocLimit.toString(), include_docs: true});
- promise = this.database.allDocs.fetch();
- } else {
- promise.resolve();
- }
-
- promise.then(function () {
- params.docs = that.database.allDocs.map(function (model) { return model.get('doc');});
-
- var queryPromise = pouchdb.runViewQuery({map: mapVal, reduce: reduceVal}, params);
- queryPromise.then(function (results) {
- FauxtonAPI.triggerRouteEvent('updatePreviewDocs', {rows: results.rows, ddoc: that.getCurrentDesignDoc().id, view: that.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') {
- 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);
- },
-
- toggleIndexNav: function (event) {
- var $targetId = this.$(event.target).attr('id'),
- $previousTab = this.$(this.$('li.active a').attr('href')),
- $targetTab = this.$(this.$(event.target).attr('href'));
-
- if ($targetTab.attr('id') !== $previousTab.attr('id')) {
- $previousTab.removeAttr('style');
- }
-
- if ($targetId === 'index-nav') {
- if (this.newView) { return; }
- var that = this;
- $('#dashboard-content').scrollTop(0); //scroll up
- $targetTab.toggle('slow', function(){
- that.showEditors();
- });
- } else {
- $targetTab.toggle('slow');
- }
- },
-
- serialize: function() {
- return {
- 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();
- },
-
- beforeRender: function () {
-
- if (this.newView) {
- this.reduceFunStr = '_sum';
- 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(ddocDecode).dDocModel();
- this.reduceFunStr = this.model.viewHasReduce(this.viewName);
- this.setView('#ddoc-info', new Views.DdocInfo({model: this.ddocInfo }));
- }
-
- this.designDocSelector = this.setView('.design-doc-group', new Views.DesignDocSelector({
- collection: this.ddocs,
- ddocName: this.model.id,
- database: this.database
- }));
-
- this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({
- updateViewFn: this.updateView,
- previewFn: this.previewView,
- database: this.database,
- viewName: this.viewName,
- ddocName: this.model.id,
- hasReduce: this.hasReduce()
- }));
- },
-
- afterRender: function() {
- if (this.params) {
- this.advancedOptions.updateFromParams(this.params);
- }
-
- this.designDocSelector.updateDesignDoc();
- if (this.newView || this.showIndex) {
- this.showEditors();
- this.showIndex = false;
- } else {
- this.$('#index').hide();
- this.$('#index-nav').parent().removeClass('active');
- }
- },
-
- 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();
- },
-
- cleanup: function () {
- this.mapEditor && this.mapEditor.remove();
- this.reduceEditor && this.reduceEditor.remove();
- }
- });
-
- Views.JumpToDoc = FauxtonAPI.View.extend({
- template: "templates/documents/jumpdoc",
-
- initialize: function (options) {
- this.database = options.database;
- },
-
- events: {
- "submit #jump-to-doc": "jumpToDoc"
- },
-
- jumpToDoc: function (event) {
- event.preventDefault();
- var docId = this.$('#jump-to-doc-id').val().trim();
- FauxtonAPI.navigate('/database/' + app.mixins.safeURLName(this.database.id) +'/' + app.mixins.safeURLName(docId), {trigger: true});
- },
-
- afterRender: function () {
- this.typeAhead = new Components.DocSearchTypeahead({el: '#jump-to-doc-id', database: this.database});
- this.typeAhead.render();
- }
- });
-
- Views.Sidebar = FauxtonAPI.View.extend({
- template: "templates/documents/sidebar",
- events: {
- "click button#delete-database": "deleteDatabase"
- },
-
- initialize: function(options) {
- this.database = options.database;
- if (options.ddocInfo) {
- this.ddocID = options.ddocInfo.id;
- this.currView = options.ddocInfo.currView;
- }
- },
-
- deleteDatabase: function (event) {
- event.preventDefault();
-
- var result = confirm('Are you sure you want to delete this database?');
-
- if (!result) { return; }
- var databaseName = this.database.id;
- FauxtonAPI.addNotification({
- msg: "Deleting your database...",
- type: "error",
- clear: true
- });
-
- this.database.destroy().then(function () {
- FauxtonAPI.navigate('#/_all_dbs');
- FauxtonAPI.addNotification({
- msg: 'The database ' + databaseName + ' has been deleted.',
- clear: true
- });
- }).fail(function (rsp, error, msg) {
- FauxtonAPI.addNotification({
- msg: 'Could not delete the database, reason ' + msg + '.',
- type: 'error',
- clear: true
- });
- });
- },
-
- serialize: function() {
- var docLinks = FauxtonAPI.getExtensions('docLinks'),
- newLinks = FauxtonAPI.getExtensions('sidebar:newLinks'),
- addLinks = FauxtonAPI.getExtensions('sidebar:links'),
- extensionList = FauxtonAPI.getExtensions('sidebar:list');
- return {
- changes_url: '#' + this.database.url('changes'),
- permissions_url: '#' + this.database.url('app') + '/permissions',
- db_url: '#' + this.database.url('index') + '?limit=' + Databases.DocLimit,
- database: this.collection.database,
- database_url: '#' + this.database.url('app'),
- docLinks: docLinks,
- docLimit: Databases.DocLimit,
- addLinks: addLinks,
- newLinks: newLinks,
- extensionList: extensionList > 0
- };
- },
-
- buildIndexList: function(collection, selector, design){
- _.each(_.keys(collection), function(key){
- var selected = this.ddocID == "_design/"+design;
- this.insertView("ul.nav." + selector, new Views.IndexItem({
- ddoc: design,
- index: key,
- database: this.collection.database.id,
- selected: selected && key == this.currView
- }));
- }, this);
- },
-
- beforeRender: function(manage) {
-
- var sidebarListViews = FauxtonAPI.getExtensions('sidebar:list');
- _.each(sidebarListViews, function (view) {
- var extension = this.insertView('#extension-navs', view);
- extension.update(this.database, this.collection, this.viewName);
- extension.render();
- }, this);
-
-
- this.collection.each(function(design) {
- if (design.has('doc')){
- var ddoc = design.id.replace(/^_design\//,"");
- if (design.get('doc').views){
- this.buildIndexList(design.get('doc').views, "views", ddoc);
- }
- }
- }, this);
- },
-
-
- afterRender: function () {
- if (this.selectedTab) {
- this.setSelectedTab(this.selectedTab);
- }
- },
-
- setSelectedTab: function (selectedTab) {
- this.selectedTab = selectedTab;
- this.$('li').removeClass('active');
- this.$('#' + selectedTab).parent().addClass('active');
- }
- });
-
- Views.Indexed = FauxtonAPI.View.extend({});
-
- Views.Changes = FauxtonAPI.View.extend({
- template: "templates/documents/changes",
-
- establish: function() {
- return [ this.model.changes.fetch()];
- },
-
- serialize: function () {
- return {
- changes: this.model.changes.toJSON(),
- database: this.model
- };
- },
-
- afterRender: function(){
- prettyPrint();
- }
- });
-
- Views.DdocInfo = FauxtonAPI.View.extend({
- template: "templates/documents/ddoc_info",
-
- initialize: function (options) {
- this.refreshTime = options.refreshTime || 5000;
- this.listenTo(this.model, 'change', this.render);
- },
-
- serialize: function () {
- return {
- view_index: this.model.get('view_index')
- };
- },
-
- afterRender: function () {
- this.startRefreshInterval();
- },
-
- startRefreshInterval: function () {
- var model = this.model;
-
- // Interval already set
- if (this.intervalId) { return ; }
-
- this.intervalId = setInterval(function () {
- model.fetch();
- }, this.refreshTime);
- },
-
- stopRefreshInterval: function () {
- clearInterval(this.intervalId);
- },
-
- cleanup: function () {
- this.stopRefreshInterval();
- }
- });
-
- Documents.Views = Views;
- return Documents;
-});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/89810cce/src/fauxton/app/modules/fauxton/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/fauxton/base.js b/src/fauxton/app/modules/fauxton/base.js
deleted file mode 100644
index cf6305c..0000000
--- a/src/fauxton/app/modules/fauxton/base.js
+++ /dev/null
@@ -1,275 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-define([
- "app",
- // Libs
- "backbone",
- "resizeColumns"
-
-],
-
-function(app, Backbone, resizeColumns) {
-
- //resizeAnimation
- app.resizeColumns = new resizeColumns({});
- app.resizeColumns.onResizeHandler();
-
- var Fauxton = app.module();
-
- Fauxton.Breadcrumbs = Backbone.View.extend({
- template: "templates/fauxton/breadcrumbs",
-
- serialize: function() {
- var crumbs = _.clone(this.crumbs);
- return {
- crumbs: crumbs
- };
- },
-
- initialize: function(options) {
- this.crumbs = options.crumbs;
- }
- });
-
- Fauxton.VersionInfo = Backbone.Model.extend({
- url: app.host
- });
-
- // TODO: this View should extend from FauxtonApi.View.
- // Chicken and egg problem, api.js extends fauxton/base.js.
- // Need to sort the loading order.
- Fauxton.Footer = Backbone.View.extend({
- template: "templates/fauxton/footer",
-
- initialize: function() {
- this.versionInfo = new Fauxton.VersionInfo();
- },
-
- establish: function() {
- return [this.versionInfo.fetch()];
- },
-
- serialize: function() {
- return {
- version: this.versionInfo.get("version")
- };
- }
- });
-
- Fauxton.NavBar = Backbone.View.extend({
- className:"navbar",
- template: "templates/fauxton/nav_bar",
- // TODO: can we generate this list from the router?
- navLinks: [
- {href:"#/_all_dbs", title:"Databases", icon: "fonticon-database", className: 'databases'}
- ],
-
- bottomNavLinks: [],
- footerNavLinks: [],
-
- serialize: function() {
- return {
- navLinks: this.navLinks,
- bottomNavLinks: this.bottomNavLinks,
- footerNavLinks: this.footerNavLinks
- };
- },
-
- addLink: function(link) {
- // link.top means it gets pushed to the top of the array,
- // link.bottomNav means it goes to the additional bottom nav
- // link.footerNav means goes to the footer nav
- if (link.top && !link.bottomNav){
- this.navLinks.unshift(link);
- } else if (link.top && link.bottomNav){
- this.bottomNavLinks.unshift(link);
- } else if (link.bottomNav) {
- this.bottomNavLinks.push(link);
- } else if (link.footerNav) {
- this.footerNavLinks.push(link);
- } else {
- this.navLinks.push(link);
- }
-
- //this.trigger("link:add");
-
- //this.render();
- },
-
- removeLink: function (removeLink) {
- var links = this.navlinks;
-
- if (removeLink.bottomNav) {
- links = this.bottomNavLinks;
- } else if (removeLink.footerNav) {
- links = this.footerNavLinks;
- }
-
- var foundIndex = -1;
-
- _.each(links, function (link, index) {
- if (link.title === removeLink.title) {
- foundIndex = index;
- }
- });
-
- if (foundIndex === -1) {return;}
- links.splice(foundIndex, 1);
- this.render();
- },
-
- afterRender: function(){
-
- $('#primary-navbar li[data-nav-name="' + app.selectedHeader + '"]').addClass('active');
-
- var menuOpen = true;
- var $selectorList = $('body');
- $('.brand').off();
- $('.brand').on({
- click: function(e){
- if(!$(e.target).is('a')){
- toggleMenu();
- }
- }
- });
-
- function toggleMenu(){
- $selectorList.toggleClass('closeMenu');
- menuOpen = $selectorList.hasClass('closeMenu');
- app.resizeColumns.onResizeHandler();
- }
-
- $('#primary-navbar').on("click", ".nav a", function(){
- if (!($selectorList.hasClass('closeMenu'))){
- setTimeout(
- function(){
- $selectorList.addClass('closeMenu');
- app.resizeColumns.onResizeHandler();
- },3000);
-
- }
- });
-
- app.resizeColumns.initialize();
- },
-
- beforeRender: function () {
- this.addLinkViews();
- },
-
- addLinkViews: function () {
- var that = this;
-
- _.each(_.union(this.navLinks, this.bottomNavLinks), function (link) {
- if (!link.view) { return; }
-
- //TODO check if establish is a function
- var establish = link.establish || [];
- $.when.apply(null, establish).then( function () {
- var selector = link.bottomNav ? '#bottom-nav-links' : '#nav-links';
- that.insertView(selector, link.view).render();
- });
- }, this);
- }
-
- // TODO: ADD ACTIVE CLASS
- });
-
- Fauxton.ApiBar = Backbone.View.extend({
- template: "templates/fauxton/api_bar",
- endpoint: '_all_docs',
-
- documentation: 'docs',
-
- events: {
- "click .api-url-btn" : "toggleAPIbar"
- },
-
- toggleAPIbar: function(e){
- var $currentTarget = $(e.currentTarget).find('span');
- if ($currentTarget.hasClass("fonticon-plus")){
- $currentTarget.removeClass("fonticon-plus").addClass("fonticon-minus");
- }else{
- $currentTarget.removeClass("fonticon-minus").addClass("fonticon-plus");
- }
-
- $('.api-navbar').toggle();
-
- },
-
- serialize: function() {
- return {
- endpoint: this.endpoint,
- documentation: this.documentation
- };
- },
-
- hide: function(){
- this.$el.addClass('hide');
- },
- show: function(){
- this.$el.removeClass('hide');
- },
- update: function(endpoint) {
- this.show();
- this.endpoint = endpoint[0];
- this.documentation = endpoint[1];
- this.render();
- }
-
- });
-
- Fauxton.Notification = Backbone.View.extend({
- fadeTimer: 5000,
-
- initialize: function(options) {
- this.msg = options.msg;
- this.type = options.type || "info";
- this.selector = options.selector;
- this.fade = options.fade === undefined ? true : options.fade;
- this.clear = options.clear;
- this.data = options.data || "";
- this.template = options.template || "templates/fauxton/notification";
- },
-
- serialize: function() {
- return {
- data: this.data,
- msg: this.msg,
- type: this.type
- };
- },
-
- delayedFade: function() {
- var that = this;
- if (this.fade) {
- setTimeout(function() {
- that.$el.fadeOut();
- }, this.fadeTimer);
- }
- },
-
- renderNotification: function(selector) {
- selector = selector || this.selector;
- if (this.clear) {
- $(selector).html('');
- }
- this.render().$el.appendTo(selector);
- this.delayedFade();
- return this;
- }
- });
-
-
- return Fauxton;
-});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/89810cce/src/fauxton/app/modules/fauxton/components.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/fauxton/components.js b/src/fauxton/app/modules/fauxton/components.js
deleted file mode 100644
index a9f45ad..0000000
--- a/src/fauxton/app/modules/fauxton/components.js
+++ /dev/null
@@ -1,337 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-define('ace_configuration', ["app", "ace/ace"], function (app, ace) {
- var path = app.host + app.root + 'js/ace';
- var config = require("ace/config");
- config.set("packaged", true);
- config.set("workerPath",path);
- config.set("modePath",path);
- config.set("themePath", path);
- return ace;
-});
-
-define([
- "app",
- // Libs
- "api",
- "ace_configuration",
-],
-
-function(app, FauxtonAPI, ace) {
- var Components = app.module();
-
- Components.Pagination = FauxtonAPI.View.extend({
- template: "templates/fauxton/pagination",
-
- initialize: function(options) {
- this.page = parseInt(options.page, 10);
- this.perPage = options.perPage;
- this.total = options.total;
- this.totalPages = Math.ceil(this.total / this.perPage);
- this.urlFun = options.urlFun;
- },
-
- serialize: function() {
- return {
- page: this.page,
- perPage: this.perPage,
- total: this.total,
- totalPages: this.totalPages,
- urlFun: this.urlFun
- };
- }
- });
-
- Components.IndexPagination = FauxtonAPI.View.extend({
- template: "templates/fauxton/index_pagination",
- events: {
- "click a": 'scrollTo',
- "click a#next": 'nextClicked',
- "click a#previous": 'previousClicked'
- },
-
- scrollTo: function () {
- if (!this.scrollToSelector) { return; }
- $(this.scrollToSelector).animate({ scrollTop: 0 }, 'slow');
- },
-
- initialize: function (options) {
- this.previousUrlfn = options.previousUrlfn;
- this.nextUrlfn = options.nextUrlfn;
- this.canShowPreviousfn = options.canShowPreviousfn;
- this.canShowNextfn = options.canShowNextfn;
- this.scrollToSelector = options.scrollToSelector;
- _.bindAll(this);
- this.previousParams = [];
- },
-
- previousClicked: function (event) {
- event.preventDefault();
- event.stopPropagation();
- if (!this.canShowPreviousfn()) { return; }
- FauxtonAPI.navigate(this.previousUrlfn(), {trigger: false});
- FauxtonAPI.triggerRouteEvent('paginate', 'previous');
- },
-
- nextClicked: function (event) {
- event.preventDefault();
- event.stopPropagation();
- if (!this.canShowNextfn()) { return; }
-
- var params = _.clone(this.collection.params);
-
- if (params) {
- this.previousParams.push(params);
- }
-
- FauxtonAPI.navigate(this.nextUrlfn(), {trigger: false});
- FauxtonAPI.triggerRouteEvent('paginate', 'next');
- },
-
- serialize: function () {
- return {
- canShowNextfn: this.canShowNextfn,
- canShowPreviousfn: this.canShowPreviousfn,
- };
- },
-
- pageLimit: function () {
- var limit = 20;
-
- if (this.collection.params.limit && this.collection.skipFirstItem) {
- limit = parseInt(this.collection.params.limit, 10) - 1;
- } else if (this.collection.params.limit) {
- limit = parseInt(this.collection.params.limit, 10);
- }
-
- return limit;
- },
-
- pageStart: function () {
- return (this.previousParams.length * this.pageLimit()) + 1;
-
- },
-
- pageEnd: function () {
- return (this.previousParams.length * this.pageLimit()) + this.pageLimit();
- }
-
- });
-
- //TODO allow more of the typeahead options.
- //Current this just does what we need but we
- //need to support the other typeahead options.
- Components.Typeahead = FauxtonAPI.View.extend({
-
- initialize: function (options) {
- this.source = options.source;
- _.bindAll(this);
- },
-
- afterRender: function () {
- var onUpdate = this.onUpdate;
-
- this.$el.typeahead({
- source: this.source,
- updater: function (item) {
- if (onUpdate) {
- onUpdate(item);
- }
-
- return item;
- }
- });
- }
-
- });
-
-
- Components.DbSearchTypeahead = Components.Typeahead.extend({
- initialize: function (options) {
- this.dbLimit = options.dbLimit || 30;
- this.onUpdate = options.onUpdate;
- _.bindAll(this);
- },
- source: function(query, process) {
- var url = [
- app.host,
- "/_all_dbs?startkey=%22",
- query,
- "%22&endkey=%22",
- query,
- "\u9999",
- "%22&limit=",
- this.dbLimit
- ].join('');
-
- if (this.ajaxReq) { this.ajaxReq.abort(); }
-
- this.ajaxReq = $.ajax({
- cache: false,
- url: url,
- dataType: 'json',
- success: function(data) {
- process(data);
- }
- });
- }
- });
-
- Components.DocSearchTypeahead = Components.Typeahead.extend({
- initialize: function (options) {
- this.docLimit = options.docLimit || 30;
- this.database = options.database;
- _.bindAll(this);
- },
- source: function(query, process) {
- var url = [
- app.host,
- "/",
- this.database.id,
- "/_all_docs?startkey=%22",
- query,
- "%22&endkey=%22",
- query,
- "\u9999",
- "%22&limit=",
- this.docLimit
- ].join('');
-
- if (this.ajaxReq) { this.ajaxReq.abort(); }
-
- this.ajaxReq = $.ajax({
- cache: false,
- url: url,
- dataType: 'json',
- success: function(data) {
- var ids = _.map(data.rows, function (row) {
- return row.id;
- });
- process(ids);
- }
- });
- }
- });
-
- Components.Editor = FauxtonAPI.View.extend({
- initialize: function (options) {
- this.editorId = options.editorId;
- this.mode = options.mode || "json";
- this.commands = options.commands;
- this.theme = options.theme || 'crimson_editor';
- this.couchJSHINT = options.couchJSHINT;
- this.edited = false;
- },
-
- afterRender: function () {
- this.editor = ace.edit(this.editorId);
- this.setHeightToLineCount();
- this.editor.setTheme("ace/theme/" + this.theme);
- this.editor.getSession().setMode("ace/mode/" + this.mode);
- this.editor.getSession().setUseWrapMode(true);
- this.editor.setShowPrintMargin(false);
- this.editor.gotoLine(2);
- this.addCommands();
-
- if (this.couchJSHINT) {
- this.removeIncorrectAnnotations();
- }
-
- var that = this;
- this.editor.getSession().on('change', function () {
- that.setHeightToLineCount();
- that.edited = true;
- });
-
- $(window).on('beforeunload.editor', function() {
- if (that.edited) {
- return 'Your changes have not been saved. Click cancel to return to the document.';
- }
- });
-
- FauxtonAPI.beforeUnload("editor", function (deferred) {
- if (that.edited) {
- return 'Your changes have not been saved. Click cancel to return to the document.';
- }
- });
- },
-
- cleanup: function () {
- $(window).off('beforeunload.editor');
- FauxtonAPI.removeBeforeUnload("editor");
- },
-
- setHeightToLineCount: function () {
- var lines = this.editor.getSession().getDocument().getLength();
- this.editor.setOptions({
- maxLines: lines
- });
-
- this.editor.resize();
- },
-
- addCommands: function () {
- _.each(this.commands, function (command) {
- this.editor.commands.addCommand(command);
- }, this);
- },
-
- removeIncorrectAnnotations: function () {
- var editor = this.editor;
-
- this.editor.getSession().on("changeAnnotation", function(){
- var annotations = editor.getSession().getAnnotations();
-
- var newAnnotations = _.reduce(annotations, function (annotations, error) {
- if (!FauxtonAPI.isIgnorableError(error.raw)) {
- annotations.push(error);
- }
- return annotations;
- }, []);
-
- if (annotations.length !== newAnnotations.length) {
- editor.getSession().setAnnotations(newAnnotations);
- }
- });
- },
-
- editSaved: function () {
- this.edited = false;
- },
-
- setValue: function (data, lineNumber) {
- lineNumber = lineNumber ? lineNumber : -1;
- this.editor.setValue(data, lineNumber);
- },
-
- getValue: function () {
- return this.editor.getValue();
- },
-
- getAnnotations: function () {
- return this.editor.getSession().getAnnotations();
- },
-
- hadValidCode: function () {
- var errors = this.getAnnotations();
- // By default CouchDB view functions don't pass lint
- return _.every(errors, function(error) {
- return FauxtonAPI.isIgnorableError(error.raw);
- },this);
- }
-
- });
-
- return Components;
-});
-