{"action":"created","comment":{"url":"https://api.github.com/repos/apache/couchdb-fauxton/pulls/comments/27435599","id":27435599,"diff_hunk":"@@ -0,0 +1,589 @@\n+// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n+// use this file except in compliance with the License. You may obtain a copy of\n+// the License at\n+//\n+//   http://www.apache.org/licenses/LICENSE-2.0\n+//\n+// Unless required by applicable law or agreed to in writing, software\n+// distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n+// License for the specific language governing permissions and limitations under\n+// the License.\n+\n+define([\n+  'app',\n+  'api',\n+  'react',\n+  'addons/activetasks/stores',\n+  'addons/activetasks/resources',\n+  'addons/activetasks/actions'\n+], function (app, FauxtonAPI, React, Stores, Resources, Actions) {\n+\n+  var activeTasksStore = Stores.activeTasksStore;\n+  var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;\n+\n+  var ActiveTasksController = React.createClass({\n+\n+    getStoreState: function () {\n+      return {\n+        collection: activeTasksStore.getCollection(),\n+        searchTerm: activeTasksStore.getSearchTerm(),\n+        selectedRadio: activeTasksStore.getSelectedRadio(),\n+\n+        sortByHeader: activeTasksStore.getSortByHeader(),\n+        headerIsAscending: activeTasksStore.getHeaderIsAscending(),\n+\n+        setPolling: activeTasksStore.setPolling,\n+        clearPolling: activeTasksStore.clearPolling,\n+      };\n+    },\n+\n+    getInitialState: function () {\n+      return this.getStoreState();\n+    },\n+\n+    componentDidMount: function () {\n+      this.state.setPolling();\n+      activeTasksStore.on('change', this.onChange, this);\n+    },\n+\n+    componentWillUnmount: function () {\n+      this.state.clearPolling();\n+      activeTasksStore.off('change', this.onChange, this);\n+    },\n+\n+    onChange: function () {\n+      this.setState(this.getStoreState());\n+    },\n+\n+    setNewSearchTerm: function (e) {\n+      Actions.setSearchTerm(e.target.value);\n+    },\n+\n+    //radio buttons\n+    switchTab: function (e) {\n+      var newRadioButton = e.target.value;\n+      Actions.switchTab(newRadioButton);\n+    },\n+\n+    tableHeaderOnClick: function (e) {\n+      var headerClicked = e.target.value;\n+      Actions.sortByColumnHeader(headerClicked);\n+    },\n+\n+    render: function () {\n+      var collection = this.state.collection;\n+      var searchTerm = this.state.searchTerm;\n+      var selectedRadio = this.state.selectedRadio;\n+      var sortByHeader = this.state.sortByHeader;\n+      var headerIsAscending = this.state.headerIsAscending;\n+\n+      var setSearchTerm = this.setNewSearchTerm;\n+      var onTableHeaderClick = this.tableHeaderOnClick;\n+\n+      if (collection.length === 0 ) {\n+        return (<div className=\"active-tasks\"><tr><td><p>  No active tasks. </p></td></tr></div>);\n+      } else {\n+        return (\n+          <div className=\"scrollable\">\n+            <div className=\"inner\">\n+              <ActiveTasksFilter \n+                searchTerm={searchTerm} \n+                selectedRadio={selectedRadio} \n+                onSearch={setSearchTerm} \n+                onRadioClick={this.switchTab}/>\n+              <ActiveTaskTable \n+                collection={collection} \n+                searchTerm={searchTerm} \n+                selectedRadio={selectedRadio}\n+                onTableHeaderClick={onTableHeaderClick}\n+                sortByHeader={sortByHeader}\n+                headerIsAscending={headerIsAscending} />\n+            </div>\n+          </div>\n+        );\n+      }\n+    }\n+  });\n+\n+  var ActiveTasksFilter = React.createClass({\n+    getStoreState: function () {\n+      return {\n+        isFilterTrayVisible: false\n+      };\n+    },\n+\n+    getInitialState: function () {\n+      return this.getStoreState();\n+    },\n+\n+    toggleFilterTray: function () {\n+      this.setState({\n+        isFilterTrayVisible : !this.state.isFilterTrayVisible\n+      });\n+    },\n+\n+    render: function () {\n+      var filterTray = '';\n+\n+      if (this.state.isFilterTrayVisible) {\n+        filterTray = <ActiveTasksFilterTray \n+                        key=\"filter-tray\" \n+                        selectedRadio={this.props.selectedRadio}\n+                        onSearch={this.props.onSearch} \n+                        onRadioClick={this.props.onRadioClick} />;\n+      }\n+\n+      return (\n+        <div id=\"dashboard-upper-content\">\n+          <div className=\"dashboard-upper-menu active-tasks\">\n+            <ActiveTasksFilterTab onClick={this.toggleFilterTray} />\n+          </div>\n+          <ReactCSSTransitionGroup \n+            className=\"dashboard-lower-menu\" \n+            transitionName=\"toggleFilterTray\" \n+            component=\"div\" >\n+            {filterTray}\n+          </ReactCSSTransitionGroup>\n+        </div>\n+      );\n+    }\n+  });\n+\n+  var ActiveTasksFilterTab = React.createClass({\n+    render: function () {\n+      return (\n+        <ul className=\"nav nav-tabs\" id=\"db-views-tabs-nav\">\n+          <li>\n+            <a id=\"toggle-filter-tab\"\n+               className=\"toggle-filter-tab\"\n+               data-bypass=\"true\" \n+               data-toggle=\"button\"\n+               onClick={this.props.onClick}>\n+              <i className=\"fonticon fonticon-plus\"></i>\n+              Filter\n+            </a>\n+          </li>\n+        </ul>);\n+    }\n+  });\n+\n+  var ActiveTasksFilterTray = React.createClass({\n+    render: function () {\n+      return (\n+        <div className=\"filter-tray\">\n+          <ActiveTasksFilterTrayCheckBoxes \n+            onRadioClick={this.props.onRadioClick} \n+            selectedRadio={this.props.selectedRadio} />\n+          <input  \n+            className=\"searchbox\" \n+            type=\"text\" \n+            name=\"search\" \n+            placeholder=\"Search for databases...\" \n+            value={this.props.searchTerm}\n+            onChange={this.props.onSearch} />  \n+        </div>\n+      );\n+    }\n+  });\n+\n+  var ActiveTasksFilterTrayCheckBoxes = React.createClass({\n+\n+    radioNames : [\n+      'All Tasks',\n+      'Replication',\n+      'Database Compaction',\n+      'Indexer',\n+      'View Compaction'\n+    ],\n+\n+    checked: function (radioName) {\n+      return this.props.selectedRadio == radioName;\n+    },\n+\n+    createCheckboxes: function () {\n+      var onRadioClick = this.props.onRadioClick;\n+      return (\n+        this.radioNames.map(function (radioName) {\n+          var checked = this.checked(radioName);\n+          var radioClassName = \"radio-\" + radioName.replace(' ', '-');\n+          return (\n+            <li className=\"active-tasks-one-checkbox\" key={radioName+\"li\"}>\n+              <input\n+                  id={radioName.replace(' ', '-')}\n+                  type=\"radio\"\n+                  key ={radioName} \n+                  name=\"radio-button-active-task-filter-tray\" \n+                  value={radioName}\n+                  checked={checked}\n+                  onChange={onRadioClick} />\n+              <label htmlFor={radioName} className=\"active-tasks-checkbox-label\">\n+              {radioName}\n+              </label>\n+            </li>\n+          );\n+        }.bind(this))\n+      );\n+    },\n+\n+    render: function () {\n+      var filterCheckboxes = this.createCheckboxes();\n+      return (\n+        <ul className=\"filter-checkboxes\">\n+          <form className=\"filter-checkboxes-form\">\n+          {filterCheckboxes}\n+          </form>\n+        </ul>\n+      );\n+    }\n+  });\n+\n+  var ActiveTaskTable = React.createClass({\n+    render: function () {\n+      var collection = this.props.collection;\n+      var selectedRadio = this.props.selectedRadio;\n+      var searchTerm = this.props.searchTerm;\n+      var sortByHeader = this.props.sortByHeader;\n+      var onTableHeaderClick = this.props.onTableHeaderClick;\n+      var headerIsAscending = this.props.headerIsAscending;\n+\n+      return (\n+        <div id=\"dashboard-lower-content\">\n+          <table className=\"table table-bordered table-striped active-tasks\">\n+            <ActiveTasksTableHeader \n+              onTableHeaderClick={onTableHeaderClick}\n+              sortByHeader={sortByHeader}\n+              headerIsAscending={headerIsAscending}/>\n+            <ActiveTasksTableBody \n+              collection={collection} \n+              selectedRadio={selectedRadio} \n+              searchTerm={searchTerm}/>\n+          </table>\n+        </div>\n+      );\n+    }\n+  });\n+\n+  var ActiveTasksTableHeader = React.createClass({\n+    headerNames : [\n+      ['type', 'Type'],\n+      ['database', 'Database'],\n+      ['started_on', 'Started On'],\n+      ['updated_on', 'Updated On'],\n+      ['pid', 'PID'],\n+      ['progress', 'Status']\n+    ],\n+\n+    createTableHeadingFields: function () {\n+      var onTableHeaderClick = this.props.onTableHeaderClick;\n+      var sortByHeader = this.props.sortByHeader;\n+      var headerIsAscending = this.props.headerIsAscending;\n+      return (\n+        this.headerNames.map(function (header) {\n+          return (\n+            <TableHeader \n+              HeaderName={header[0]}\n+              DisplayName={header[1]}\n+              key={header[0]}\n+              onTableHeaderClick={onTableHeaderClick}\n+              sortByHeader={sortByHeader}\n+              headerIsAscending={headerIsAscending} />\n+          );\n+        })\n+      );\n+    },\n+\n+    render: function () {\n+      var tableHeadingFields = this.createTableHeadingFields();\n+      return (\n+        <thead>\n+          <tr>{tableHeadingFields}</tr>\n+        </thead>\n+      );\n+    }\n+  });\n+\n+  var TableHeader = React.createClass({\n+    arrow: function () {\n+      var sortBy = this.props.sortByHeader;\n+      var currentName = this.props.HeaderName;\n+      var headerIsAscending = this.props.headerIsAscending;\n+      var arrow = headerIsAscending ? 'icon icon-caret-up' : 'icon icon-caret-down';\n+\n+      if (sortBy === currentName) {\n+        return <i className={arrow}></i>;\n+      }\n+    },\n+\n+    render: function () {\n+      var arrow = this.arrow();\n+      var th_class = 'header-field ' + this.props.HeaderName;\n+\n+      return (\n+        <input\n+          type=\"radio\"\n+          name=\"header-field\"\n+          id={this.props.HeaderName}\n+          value={this.props.HeaderName}\n+          className=\"header-field radio\"\n+          onChange={this.props.onTableHeaderClick}>\n+          <th className={th_class} value={this.props.HeaderName}>\n+            <label \n+              className=\"header-field label-text\"\n+              htmlFor={this.props.HeaderName}>\n+              {this.props.DisplayName} {arrow}\n+            </label>\n+          </th>\n+        </input>\n+      );\n+    }\n+  });\n+\n+  var ActiveTasksTableBody = React.createClass({\n+\n+    getStoreState: function () {\n+      return {\n+        filteredTable: activeTasksStore.getFilteredTable(this.props.collection)\n+      };\n+    },\n+\n+    getInitialState: function () {\n+      return this.getStoreState();\n+    },\n+\n+    componentWillReceiveProps: function (nextProps) {\n+      this.setState({\n+        filteredTable:\n+          activeTasksStore.getFilteredTable(this.props.collection)\n+      });\n+    },\n+\n+    createRows: function () {\n+      var isThereASearchTerm = this.props.searchTerm.trim() === \"\";\n+\n+      if (this.state.filteredTable.length === 0) {\n+        return isThereASearchTerm ? this.noActiveTasks() : this.noActiveTasksMatchFilter();\n+      }\n+\n+      return _.map(this.state.filteredTable, function (item, iteration) {\n+        return <ActiveTaskTableBodyContents key={Math.random()} item={item} />;\n+      });\n+    },\n+\n+    noActiveTasks: function () {\n+      return (\n+        <tr className=\"no-matching-database-on-search\">\n+          <td  colSpan=\"6\">No active {this.props.selectedRadio} tasks.</td>\n+        </tr>\n+      );\n+    },\n+\n+    noActiveTasksMatchFilter: function () {\n+      return (\n+        <tr className=\"no-matching-database-on-search\">\n+          <td colSpan=\"6\">No active {this.props.selectedRadio} tasks match with filter: \"{this.props.searchTerm}\".</td>\n+        </tr>\n+      );\n+    },\n+\n+    render: function () {\n+      var tableBody = this.createRows();\n+      return (\n+        <tbody className=\"js-tasks-go-here\">\n+        {tableBody}\n+        </tbody>\n+      );\n+    }\n+  });\n+\n+  var ActiveTaskTableBodyContents = React.createClass({\n+    getInfo: function (item) {\n+      return {\n+        type : item.type,\n+        objectField: activeTasksHelpers.getDatabaseFieldMessage(item) ,\n+        started_on: activeTasksHelpers.getTimeInfo(item.started_on),\n+        updated_on: activeTasksHelpers.getTimeInfo(item.updated_on),\n+        pid: item.pid.replace(/[<>]/g, ''),\n+        progress: activeTasksHelpers.getProgressMessage(item),\n+      };\n+    },\n+\n+    multilineMessage: function (messageArray, optionalClassName) {\n+\n+      if (!optionalClassName) {\n+        optionalClassName = '';\n+      }\n+      var cssClasses = 'multiline-active-tasks-message ' + optionalClassName;\n+\n+      return messageArray.map(function (msgLine, iterator) {\n+        return <p key={iterator} className={cssClasses}>{msgLine}</p>;\n+      });\n+    },\n+\n+    render: function () {\n+      var rowData =  this.getInfo(this.props.item);\n+      var objectFieldMsg = this.multilineMessage(rowData.objectField);\n+      var startedOnMsg = this.multilineMessage(rowData.started_on, 'time');\n+      var updatedOnMsg = this.multilineMessage(rowData.updated_on, 'time');\n+      var progressMsg = this.multilineMessage(rowData.progress);\n+\n+      return (\n+        <tr>\n+          <td>{rowData.type}</td>\n+          <td>{objectFieldMsg}</td>\n+          <td>{startedOnMsg}</td>\n+          <td>{updatedOnMsg}</td>\n+          <td>{rowData.pid}</td>\n+          <td>{progressMsg}</td>\n+        </tr>\n+      );\n+    }\n+  });\n+\n+  var ActiveTasksPollingWidget = React.createClass({\n+\n+    getStoreState: function () {\n+      return {\n+        pollingInterval:  activeTasksStore.getPollingInterval()\n+      };\n+    },\n+\n+    getInitialState: function () {\n+      return this.getStoreState();\n+    },\n+\n+    componentDidMount: function () {\n+      activeTasksStore.on('change', this.onChange, this);\n+    },\n+\n+    onChange: function () {\n+      if (this.isMounted()) {\n+        this.setState(this.getStoreState());\n+      }\n+    },\n+\n+    pollingIntervalChange: function (event) {\n+      Actions.changePollingInterval(event.target.value);\n+    },\n+\n+    getPluralForLabel: function () {\n+      return this.state.pollingInterval === \"1\" ? '' : 's';\n+    },\n+\n+    createPollingWidget: function () {\n+      var pollingInterval = this.state.pollingInterval;\n+      var s = this.getPluralForLabel();\n+      var onChangeHandle = this.pollingIntervalChange;\n+\n+      return (\n+        <ul className=\"polling-interval-widget\">\n+          <li className=\"polling-interval-name\">Polling interval\n+            <label className=\"polling-interval-time-label\" htmlFor=\"pollingRange\"> \n+              <span>{pollingInterval}</span> second{s} \n+            </label>\n+          </li>\n+          <li>\n+            <input \n+              id=\"pollingRange\" \n+              type=\"range\" \n+              min=\"1\" \n+              max=\"30\" \n+              step=\"1\" \n+              value={pollingInterval} \n+              onChange={onChangeHandle}/>\n+          </li>\n+        </ul>\n+      );\n+    },\n+\n+    render: function () {\n+      var pollingWidget = this.createPollingWidget();\n+\n+      return  <div>{pollingWidget}</div>;\n+    }\n+  });\n+\n+  var activeTasksHelpers = {\n+    getTimeInfo: function (timeStamp) {\n+      var timeMessage = [app.helpers.formatDate(timeStamp)];\n+      timeMessage.push(app.helpers.getDateFromNow(timeStamp));\n+      return timeMessage;\n+    },\n+\n+    getDatabaseFieldMessage: function (item) {\n+      var type = item.type;\n+      var databaseFieldMessage = [];\n+\n+      if (type === 'replication') {\n+        databaseFieldMessage.push('From: ' + item.source);\n+        databaseFieldMessage.push('To: ' + item.target);\n+      } else if (type === 'indexer') {\n+        databaseFieldMessage.push(item.database);\n+        databaseFieldMessage.push('(View: ' + item.design_document + ')');\n+      } else {\n+        databaseFieldMessage.push(item.database);\n+      }\n+\n+      return databaseFieldMessage;\n+    },\n+\n+    getProgressMessage: function (item) {\n+      var progressMessage = [];\n+      var type = item.type;\n+\n+      if (item.hasOwnProperty('progress')) {\n+        progressMessage.push('Progress: ' + item.progress + '%');\n+      }\n+\n+      if (type === 'indexer') {\n+        progressMessage.push(\n+          'Processed ' + item.changes_done + ' of ' + item.total_changes + ' changes.'\n+        );\n+      } else if (type === 'replication') {\n+        progressMessage.push(item.docs_written + ' docs written.');\n+\n+        if (item.hasOwnProperty('changes_pending')) {\n+          progressMessage.push(item.changes_pending + ' pending changes.');\n+        }\n+      }\n+\n+      if (item.hasOwnProperty('source_seq')) {\n+        progressMessage.push('Current source sequence: ' + item.source_seq + '. ');\n+      }\n+\n+      if (item.hasOwnProperty('changes_done')) {\n+        progressMessage.push(item.changes_done + ' Changes done.');\n+      }\n+\n+      return progressMessage;\n+    }\n+  };\n+\n+  return {\n+    renderActiveTasks: function (el) {\n+      React.render(<ActiveTasksController />, el);\n+    },\n+\n+    removeActiveTasks: function (el) {","path":"app/addons/activetasks/components.react.jsx","position":567,"original_position":567,"commit_id":"5447bc779406ddaa8234d24f0ea099a37e8ea2ca","original_commit_id":"5447bc779406ddaa8234d24f0ea099a37e8ea2ca","user":{"login":"benkeen","id":512116,"avatar_url":"https://avatars.githubusercontent.com/u/512116?v=3","gravatar_id":"","url":"https://api.github.com/users/benkeen","html_url":"https://github.com/benkeen","followers_url":"https://api.github.com/users/benkeen/followers","following_url":"https://api.github.com/users/benkeen/following{/other_user}","gists_url":"https://api.github.com/users/benkeen/gists{/gist_id}","starred_url":"https://api.github.com/users/benkeen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/benkeen/subscriptions","organizations_url":"https://api.github.com/users/benkeen/orgs","repos_url":"https://api.github.com/users/benkeen/repos","events_url":"https://api.github.com/users/benkeen/events{/privacy}","received_events_url":"https://api.github.com/users/benkeen/received_events","type":"User","site_admin":false},"body":"Seems like we do this a lot - i.e. a custom function to remove a React element at a DOM node. Wonder if we should just add a generic `remove()` method in the main Fauxton React components section that removes an element at a node...?","created_at":"2015-03-30T21:51:27Z","updated_at":"2015-03-30T21:51:27Z","html_url":"https://github.com/apache/couchdb-fauxton/pull/317#discussion_r27435599","pull_request_url":"https://api.github.com/repos/apache/couchdb-fauxton/pulls/317","_links":{"self":{"href":"https://api.github.com/repos/apache/couchdb-fauxton/pulls/comments/27435599"},"html":{"href":"https://github.com/apache/couchdb-fauxton/pull/317#discussion_r27435599"},"pull_request":{"href":"https://api.github.com/repos/apache/couchdb-fauxton/pulls/317"}}},"pull_request":{"url":"https://api.github.com/repos/apache/couchdb-fauxton/pulls/317","id":31193494,"html_url":"https://github.com/apache/couchdb-fauxton/pull/317","diff_url":"https://github.com/apache/couchdb-fauxton/pull/317.diff","patch_url":"https://github.com/apache/couchdb-fauxton/pull/317.patch","issue_url":"https://api.github.com/repos/apache/couchdb-fauxton/issues/317","number":317,"state":"open","locked":false,"title":"Active tasks in React","user":{"login":"michellephung","id":836039,"avatar_url":"https://avatars.githubusercontent.com/u/836039?v=3","gravatar_id":"","url":"https://api.github.com/users/michellephung","html_url":"https://github.com/michellephung","followers_url":"https://api.github.com/users/michellephung/followers","following_url":"https://api.github.com/users/michellephung/following{/other_user}","gists_url":"https://api.github.com/users/michellephung/gists{/gist_id}","starred_url":"https://api.github.com/users/michellephung/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/michellephung/subscriptions","organizations_url":"https://api.github.com/users/michellephung/orgs","repos_url":"https://api.github.com/users/michellephung/repos","events_url":"https://api.github.com/users/michellephung/events{/privacy}","received_events_url":"https://api.github.com/users/michellephung/received_events","type":"User","site_admin":false},"body":"I still have to write some tests. ","created_at":"2015-03-15T01:24:43Z","updated_at":"2015-03-30T21:51:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"64f268fcd225f5f6cbe60779f9d2797be0021b42","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/apache/couchdb-fauxton/pulls/317/commits","review_comments_url":"https://api.github.com/repos/apache/couchdb-fauxton/pulls/317/comments","review_comment_url":"https://api.github.com/repos/apache/couchdb-fauxton/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/couchdb-fauxton/issues/317/comments","statuses_url":"https://api.github.com/repos/apache/couchdb-fauxton/statuses/5447bc779406ddaa8234d24f0ea099a37e8ea2ca","head":{"label":"michellephung:Active-Tasks-in-REACT","ref":"Active-Tasks-in-REACT","sha":"5447bc779406ddaa8234d24f0ea099a37e8ea2ca","user":{"login":"michellephung","id":836039,"avatar_url":"https://avatars.githubusercontent.com/u/836039?v=3","gravatar_id":"","url":"https://api.github.com/users/michellephung","html_url":"https://github.com/michellephung","followers_url":"https://api.github.com/users/michellephung/followers","following_url":"https://api.github.com/users/michellephung/following{/other_user}","gists_url":"https://api.github.com/users/michellephung/gists{/gist_id}","starred_url":"https://api.github.com/users/michellephung/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/michellephung/subscriptions","organizations_url":"https://api.github.com/users/michellephung/orgs","repos_url":"https://api.github.com/users/michellephung/repos","events_url":"https://api.github.com/users/michellephung/events{/privacy}","received_events_url":"https://api.github.com/users/michellephung/received_events","type":"User","site_admin":false},"repo":{"id":24307610,"name":"couchdb-fauxton","full_name":"michellephung/couchdb-fauxton","owner":{"login":"michellephung","id":836039,"avatar_url":"https://avatars.githubusercontent.com/u/836039?v=3","gravatar_id":"","url":"https://api.github.com/users/michellephung","html_url":"https://github.com/michellephung","followers_url":"https://api.github.com/users/michellephung/followers","following_url":"https://api.github.com/users/michellephung/following{/other_user}","gists_url":"https://api.github.com/users/michellephung/gists{/gist_id}","starred_url":"https://api.github.com/users/michellephung/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/michellephung/subscriptions","organizations_url":"https://api.github.com/users/michellephung/orgs","repos_url":"https://api.github.com/users/michellephung/repos","events_url":"https://api.github.com/users/michellephung/events{/privacy}","received_events_url":"https://api.github.com/users/michellephung/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/michellephung/couchdb-fauxton","description":"Mirror of Apache CouchDB","fork":true,"url":"https://api.github.com/repos/michellephung/couchdb-fauxton","forks_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/forks","keys_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/keys{/key_id}","collaborators_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/teams","hooks_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/hooks","issue_events_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/issues/events{/number}","events_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/events","assignees_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/assignees{/user}","branches_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/branches{/branch}","tags_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/tags","blobs_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/git/refs{/sha}","trees_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/git/trees{/sha}","statuses_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/statuses/{sha}","languages_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/languages","stargazers_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/stargazers","contributors_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/contributors","subscribers_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/subscribers","subscription_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/subscription","commits_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/commits{/sha}","git_commits_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/git/commits{/sha}","comments_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/comments{/number}","issue_comment_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/issues/comments{/number}","contents_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/contents/{+path}","compare_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/compare/{base}...{head}","merges_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/merges","archive_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/downloads","issues_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/issues{/number}","pulls_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/pulls{/number}","milestones_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/milestones{/number}","notifications_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/labels{/name}","releases_url":"https://api.github.com/repos/michellephung/couchdb-fauxton/releases{/id}","created_at":"2014-09-21T23:17:43Z","updated_at":"2015-03-30T17:03:36Z","pushed_at":"2015-03-30T20:53:09Z","git_url":"git://github.com/michellephung/couchdb-fauxton.git","ssh_url":"git@github.com:michellephung/couchdb-fauxton.git","clone_url":"https://github.com/michellephung/couchdb-fauxton.git","svn_url":"https://github.com/michellephung/couchdb-fauxton","homepage":null,"size":43671,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"apache:master","ref":"master","sha":"e9507c91ab48fc94e930b523f724d46e59cce131","user":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"repo":{"id":15993612,"name":"couchdb-fauxton","full_name":"apache/couchdb-fauxton","owner":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/apache/couchdb-fauxton","description":"Mirror of Apache CouchDB","fork":false,"url":"https://api.github.com/repos/apache/couchdb-fauxton","forks_url":"https://api.github.com/repos/apache/couchdb-fauxton/forks","keys_url":"https://api.github.com/repos/apache/couchdb-fauxton/keys{/key_id}","collaborators_url":"https://api.github.com/repos/apache/couchdb-fauxton/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/apache/couchdb-fauxton/teams","hooks_url":"https://api.github.com/repos/apache/couchdb-fauxton/hooks","issue_events_url":"https://api.github.com/repos/apache/couchdb-fauxton/issues/events{/number}","events_url":"https://api.github.com/repos/apache/couchdb-fauxton/events","assignees_url":"https://api.github.com/repos/apache/couchdb-fauxton/assignees{/user}","branches_url":"https://api.github.com/repos/apache/couchdb-fauxton/branches{/branch}","tags_url":"https://api.github.com/repos/apache/couchdb-fauxton/tags","blobs_url":"https://api.github.com/repos/apache/couchdb-fauxton/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/apache/couchdb-fauxton/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/apache/couchdb-fauxton/git/refs{/sha}","trees_url":"https://api.github.com/repos/apache/couchdb-fauxton/git/trees{/sha}","statuses_url":"https://api.github.com/repos/apache/couchdb-fauxton/statuses/{sha}","languages_url":"https://api.github.com/repos/apache/couchdb-fauxton/languages","stargazers_url":"https://api.github.com/repos/apache/couchdb-fauxton/stargazers","contributors_url":"https://api.github.com/repos/apache/couchdb-fauxton/contributors","subscribers_url":"https://api.github.com/repos/apache/couchdb-fauxton/subscribers","subscription_url":"https://api.github.com/repos/apache/couchdb-fauxton/subscription","commits_url":"https://api.github.com/repos/apache/couchdb-fauxton/commits{/sha}","git_commits_url":"https://api.github.com/repos/apache/couchdb-fauxton/git/commits{/sha}","comments_url":"https://api.github.com/repos/apache/couchdb-fauxton/comments{/number}","issue_comment_url":"https://api.github.com/repos/apache/couchdb-fauxton/issues/comments{/number}","contents_url":"https://api.github.com/repos/apache/couchdb-fauxton/contents/{+path}","compare_url":"https://api.github.com/repos/apache/couchdb-fauxton/compare/{base}...{head}","merges_url":"https://api.github.com/repos/apache/couchdb-fauxton/merges","archive_url":"https://api.github.com/repos/apache/couchdb-fauxton/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/apache/couchdb-fauxton/downloads","issues_url":"https://api.github.com/repos/apache/couchdb-fauxton/issues{/number}","pulls_url":"https://api.github.com/repos/apache/couchdb-fauxton/pulls{/number}","milestones_url":"https://api.github.com/repos/apache/couchdb-fauxton/milestones{/number}","notifications_url":"https://api.github.com/repos/apache/couchdb-fauxton/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/apache/couchdb-fauxton/labels{/name}","releases_url":"https://api.github.com/repos/apache/couchdb-fauxton/releases{/id}","created_at":"2014-01-17T08:00:08Z","updated_at":"2015-03-30T16:21:27Z","pushed_at":"2015-03-30T20:53:10Z","git_url":"git://github.com/apache/couchdb-fauxton.git","ssh_url":"git@github.com:apache/couchdb-fauxton.git","clone_url":"https://github.com/apache/couchdb-fauxton.git","svn_url":"https://github.com/apache/couchdb-fauxton","homepage":null,"size":10843,"stargazers_count":40,"watchers_count":40,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":45,"mirror_url":"git://git.apache.org/couchdb-fauxton.git","open_issues_count":13,"forks":45,"open_issues":13,"watchers":40,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/couchdb-fauxton/pulls/317"},"html":{"href":"https://github.com/apache/couchdb-fauxton/pull/317"},"issue":{"href":"https://api.github.com/repos/apache/couchdb-fauxton/issues/317"},"comments":{"href":"https://api.github.com/repos/apache/couchdb-fauxton/issues/317/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/couchdb-fauxton/pulls/317/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/couchdb-fauxton/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/couchdb-fauxton/pulls/317/commits"},"statuses":{"href":"https://api.github.com/repos/apache/couchdb-fauxton/statuses/5447bc779406ddaa8234d24f0ea099a37e8ea2ca"}}}}