You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@couchdb.apache.org by GitBox <gi...@apache.org> on 2018/11/08 19:55:49 UTC

[GitHub] Antonio-Maranhao closed pull request #1153: [partitioned dbs] Show results for partitioned views and All Docs filtered by partition key

Antonio-Maranhao closed pull request #1153: [partitioned dbs] Show results for partitioned views and All Docs filtered by partition key
URL: https://github.com/apache/couchdb-fauxton/pull/1153
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/app/addons/documents/__tests__/fetch-actions.test.js b/app/addons/documents/__tests__/fetch-actions.test.js
index ec7af92e5..7940487ec 100644
--- a/app/addons/documents/__tests__/fetch-actions.test.js
+++ b/app/addons/documents/__tests__/fetch-actions.test.js
@@ -181,10 +181,6 @@ describe('Docs Fetch API', () => {
   });
 
   describe('queryAllDocs', () => {
-    const params = {
-      limit: 21,
-      skip: 0
-    };
     const docs = {
       "total_rows": 2,
       "offset": 0,
@@ -207,12 +203,52 @@ describe('Docs Fetch API', () => {
     };
 
     it('queries _all_docs with default params', () => {
+      const params = {
+        limit: 21,
+        skip: 0
+      };
+      const fetchUrl = '/testdb/_all_docs';
+      const query = app.utils.queryString(params);
+      const url = `${fetchUrl}?${query}`;
+      fetchMock.getOnce(url, docs);
+
+      return queryAllDocs(fetchUrl, '', params).then((res) => {
+        expect(res).toEqual({
+          docType: Constants.INDEX_RESULTS_DOC_TYPE.VIEW,
+          docs: [
+            {
+              id: "foo",
+              key: "foo",
+              value: {
+                rev: "1-1390740c4877979dbe8998382876556c"
+              }
+            },
+            {
+              id: "foo2",
+              key: "foo2",
+              value: {
+                rev: "2-1390740c4877979dbe8998382876556c"
+              }
+            }]
+        });
+      });
+    });
+
+    it('queries _all_docs with a partition key', () => {
+      const partitionKey = 'key1';
+      const params = {
+        limit: 21,
+        skip: 0,
+        inclusive_end: false,
+        start_key: `"${partitionKey}:"`,
+        end_key: `"${partitionKey}:\ufff0"`
+      };
       const fetchUrl = '/testdb/_all_docs';
       const query = app.utils.queryString(params);
       const url = `${fetchUrl}?${query}`;
       fetchMock.getOnce(url, docs);
 
-      return queryAllDocs(fetchUrl, params).then((res) => {
+      return queryAllDocs(fetchUrl, partitionKey, params).then((res) => {
         expect(res).toEqual({
           docType: Constants.INDEX_RESULTS_DOC_TYPE.VIEW,
           docs: [
diff --git a/app/addons/documents/__tests__/results-toolbar.test.js b/app/addons/documents/__tests__/results-toolbar.test.js
index 8c6b4d83c..45e2a1352 100644
--- a/app/addons/documents/__tests__/results-toolbar.test.js
+++ b/app/addons/documents/__tests__/results-toolbar.test.js
@@ -28,6 +28,9 @@ describe('Results Toolbar', () => {
     isLoading: false,
     queryOptionsParams: {},
     databaseName: 'mydb',
+    fetchUrl: '/db1/_all_docs',
+    docType: Constants.INDEX_RESULTS_DOC_TYPE.VIEW,
+    hasResults: true,
     resultsStyle: {
       textOverflow: Constants.INDEX_RESULTS_STYLE.TEXT_OVERFLOW_TRUNCATED,
       fontSize: Constants.INDEX_RESULTS_STYLE.FONT_SIZE_MEDIUM
@@ -106,7 +109,7 @@ describe('Results Toolbar', () => {
     sinon.assert.calledWith(mockUpdateStyle, { fontSize: Constants.INDEX_RESULTS_STYLE.FONT_SIZE_LARGE});
   });
 
-  it.only('does not show Display Density option in JSON layout', () => {
+  it('does not show Display Density option in JSON layout', () => {
     const toolbarJson = mount(<ResultsToolBar
       {...defaultProps}
       hasResults={true}
@@ -133,4 +136,34 @@ describe('Results Toolbar', () => {
     expect(toolbarTable.find('li.header-label').at(0).text()).toBe('Display density');
     expect(toolbarTable.find('li.header-label').at(1).text()).toBe('Font size');
   });
+
+  it('shows Table, Metadata and JSON modes when querying a global view', () => {
+    const wrapper = mount(<ResultsToolBar
+      {...defaultProps}
+      hasResults={true}
+      isListDeletable={false}
+      partitionKey={''}
+      fetchUrl='/my_db/_design/ddoc1/_view/view1'/>);
+    expect(wrapper.find('button')).toHaveLength(4);
+  });
+
+  it('hides Table and JSON modes when querying a partitioned view', () => {
+    const wrapper = mount(<ResultsToolBar
+      {...defaultProps}
+      hasResults={true}
+      isListDeletable={false}
+      partitionKey={'partKey1'}
+      fetchUrl='/my_db/_partition/my_partition/_design/ddoc1/_view/view1'/>);
+    expect(wrapper.find('button')).toHaveLength(2);
+  });
+
+  it('shows Table, Metadata and JSON modes when showing All Documents filtered by partition', () => {
+    const wrapper = mount(<ResultsToolBar
+      {...defaultProps}
+      hasResults={true}
+      isListDeletable={false}
+      partitionKey={'partKey1'}
+      fetchUrl='/my_db/_all_docs'/>);
+    expect(wrapper.find('button')).toHaveLength(4);
+  });
 });
diff --git a/app/addons/documents/assets/less/index-results.less b/app/addons/documents/assets/less/index-results.less
index 8d05cfc2b..6ea7ddcde 100644
--- a/app/addons/documents/assets/less/index-results.less
+++ b/app/addons/documents/assets/less/index-results.less
@@ -97,6 +97,12 @@ a.document-result-screen__toolbar-create-btn:visited {
     padding-top: 8px;
     margin: 0 auto;
   }
+  .no-results-screen-warning {
+    text-align: center;
+    i {
+      padding-right: 0.5rem;
+    } 
+  }
 }
 .watermark-logo {
   background: transparent url('../../../../../assets/img/couch-watermark.png') no-repeat 50% 50%;
diff --git a/app/addons/documents/base.js b/app/addons/documents/base.js
index 21515ebd8..8ccf98995 100644
--- a/app/addons/documents/base.js
+++ b/app/addons/documents/base.js
@@ -119,16 +119,16 @@ FauxtonAPI.registerUrls('designDocs', {
 });
 
 FauxtonAPI.registerUrls('view', {
-  server: function (database, designDoc, viewName) {
-    return Helpers.getServerUrl('/' + database + '/_design/' + designDoc + '/_view/' + viewName);
+  server: function (database, partitionKey, designDoc, viewName) {
+    return Helpers.getServerUrl('/' + database + partitionUrlComponent(partitionKey) + '/_design/' + designDoc + '/_view/' + viewName);
   },
 
   app: function (database, designDoc) {
     return 'database/' + database + '/_design/' + designDoc + '/_view/';
   },
 
-  apiurl: function (id, designDoc, viewName) {
-    return Helpers.getApiUrl('/' + id + '/_design/' + designDoc + '/_view/' + viewName);
+  apiurl: function (id, partitionKey, designDoc, viewName) {
+    return Helpers.getApiUrl('/' + id + partitionUrlComponent(partitionKey) + '/_design/' + designDoc + '/_view/' + viewName);
   },
 
   edit: function (database, partitionKey, designDoc, indexName) {
diff --git a/app/addons/documents/components/results-toolbar.js b/app/addons/documents/components/results-toolbar.js
index 8c765c231..a610d2ffd 100644
--- a/app/addons/documents/components/results-toolbar.js
+++ b/app/addons/documents/components/results-toolbar.js
@@ -95,6 +95,7 @@ ResultsToolBar.propTypes = {
   hasResults: PropTypes.bool.isRequired,
   isListDeletable: PropTypes.bool,
   partitionKey: PropTypes.string,
+  docType: PropTypes.string,
   resultsStyle: PropTypes.object.isRequired,
   updateResultsStyle: PropTypes.func.isRequired
 };
diff --git a/app/addons/documents/header/header.js b/app/addons/documents/header/header.js
index ba7c3b4b5..52093e522 100644
--- a/app/addons/documents/header/header.js
+++ b/app/addons/documents/header/header.js
@@ -23,7 +23,9 @@ export default class BulkDocumentHeaderController extends React.Component {
     const {
       selectedLayout,
       docType,
-      queryOptionsParams
+      queryOptionsParams,
+      partitionKey,
+      fetchUrl
     } = this.props;
 
     let metadata, json, table;
@@ -38,10 +40,11 @@ export default class BulkDocumentHeaderController extends React.Component {
       return null;
     }
 
-    // reduce doesn't allow for include_docs=true, so we'll prevent JSON and table
-    // views since they force include_docs=true when reduce is checked in the
-    // query options panel.
-    if (!queryOptionsParams.reduce) {
+    // Reduce doesn't allow for include_docs=true, so we'll prevent JSON and table
+    // views since they force include_docs=true when reduce is checked in the query options panel.
+    // Partitioned queries don't supprt include_docs=true either.
+    const isAllDocsQuery = fetchUrl && fetchUrl.includes('/_all_docs');
+    if (isAllDocsQuery || (!queryOptionsParams.reduce && !partitionKey)) {
       table = <Button
         className={selectedLayout === Constants.LAYOUT_ORIENTATION.TABLE ? 'active' : ''}
         onClick={this.toggleLayout.bind(this, Constants.LAYOUT_ORIENTATION.TABLE)}
diff --git a/app/addons/documents/index-results/actions/base.js b/app/addons/documents/index-results/actions/base.js
index cd9cc881a..c39f1f4d2 100644
--- a/app/addons/documents/index-results/actions/base.js
+++ b/app/addons/documents/index-results/actions/base.js
@@ -13,6 +13,18 @@
 import ActionTypes from '../actiontypes';
 import { getDocId, getDocRev, isJSONDocBulkDeletable } from "../helpers/shared-helpers";
 
+export const partitionParamNotSupported = () => {
+  return {
+    type: ActionTypes.INDEX_RESULTS_REDUX_PARTITION_PARAM_NOT_SUPPORTED
+  };
+};
+
+export const partitionParamIsMandatory = () => {
+  return {
+    type: ActionTypes.INDEX_RESULTS_REDUX_PARTITION_PARAM_MANDATORY
+  };
+};
+
 export const nowLoading = () => {
   return {
     type: ActionTypes.INDEX_RESULTS_REDUX_IS_LOADING
diff --git a/app/addons/documents/index-results/actions/fetch.js b/app/addons/documents/index-results/actions/fetch.js
index fc8df4eb6..6fdb32c07 100644
--- a/app/addons/documents/index-results/actions/fetch.js
+++ b/app/addons/documents/index-results/actions/fetch.js
@@ -16,7 +16,7 @@ import Constants from '../../constants';
 import { errorReason } from '../helpers/shared-helpers';
 import * as IndexResultsAPI from '../api';
 import { nowLoading, newResultsAvailable, newSelectedDocs,
-  changeLayout, resetState } from './base';
+  changeLayout, resetState, partitionParamNotSupported, partitionParamIsMandatory } from './base';
 
 const maxDocLimit = 10000;
 
@@ -91,23 +91,29 @@ export const fetchDocs = (queryDocs, fetchParams, queryOptionsParams) => {
     dispatch(nowLoading());
 
     // now fetch the results
-    return queryDocs(params).then(({ docs, docType, executionStats, warning }) => {
+    return queryDocs(params).then(({ docs, docType, executionStats, warning, layout }) => {
       const {
         finalDocList,
         canShowNext
       } = removeOverflowDocsAndCalculateHasNext(docs, totalDocsRemaining, params.limit);
 
-      if (docType === Constants.INDEX_RESULTS_DOC_TYPE.MANGO_INDEX) {
-        dispatch(changeLayout(Constants.LAYOUT_ORIENTATION.JSON));
+      if (layout) {
+        dispatch(changeLayout(layout));
       }
       // dispatch that we're all done
       dispatch(newResultsAvailable(finalDocList, params, canShowNext, docType, executionStats, warning));
     }).catch((error) => {
-      FauxtonAPI.addNotification({
-        msg: 'Error running query. ' + errorReason(error),
-        type: 'error',
-        clear: true
-      });
+      if (error && error.message.includes('partition query is not supported')) {
+        dispatch(partitionParamNotSupported());
+      } else if (error && error.message.includes('`partition` parameter is mandatory')) {
+        dispatch(partitionParamIsMandatory());
+      } else {
+        FauxtonAPI.addNotification({
+          msg: 'Error running query. ' + errorReason(error),
+          type: 'error',
+          clear: true
+        });
+      }
       dispatch(resetState());
     });
   };
diff --git a/app/addons/documents/index-results/actiontypes.js b/app/addons/documents/index-results/actiontypes.js
index d69c15d44..fbd9aa2f0 100644
--- a/app/addons/documents/index-results/actiontypes.js
+++ b/app/addons/documents/index-results/actiontypes.js
@@ -30,5 +30,7 @@ export default {
   INDEX_RESULTS_REDUX_CHANGE_TABLE_HEADER_ATTRIBUTE: 'INDEX_RESULTS_REDUX_CHANGE_TABLE_HEADER_ATTRIBUTE',
   INDEX_RESULTS_REDUX_RESET_STATE: 'INDEX_RESULTS_REDUX_RESET_STATE',
   INDEX_RESULTS_REDUX_NEW_QUERY_OPTIONS: 'INDEX_RESULTS_REDUX_NEW_QUERY_OPTIONS',
+  INDEX_RESULTS_REDUX_PARTITION_PARAM_NOT_SUPPORTED: 'INDEX_RESULTS_REDUX_PARTITION_PARAM_NOT_SUPPORTED',
+  INDEX_RESULTS_REDUX_PARTITION_PARAM_MANDATORY: 'INDEX_RESULTS_REDUX_PARTITION_PARAM_MANDATORY',
   INDEX_RESULTS_SET_STYLE: 'INDEX_RESULTS_SET_STYLE'
 };
diff --git a/app/addons/documents/index-results/api.js b/app/addons/documents/index-results/api.js
index 9f836fedc..9278879b8 100644
--- a/app/addons/documents/index-results/api.js
+++ b/app/addons/documents/index-results/api.js
@@ -16,9 +16,13 @@ import app from '../../../app';
 import Constants from '../constants';
 import FauxtonAPI from '../../../core/api';
 
-export const queryAllDocs = (fetchUrl, params) => {
+export const queryAllDocs = (fetchUrl, partitionKey, params) => {
   // Exclude params 'group', 'reduce' and 'group_level' if present since they not allowed for '_all_docs'
   Object.assign(params, {reduce: undefined, group: undefined, group_level: undefined});
+  if (partitionKey) {
+    // partition filter overrides any 'between keys' values set
+    Object.assign(params, {inclusive_end: false, start_key: `"${partitionKey}:"`, end_key: `"${partitionKey}:\ufff0"`});
+  }
   const query = app.utils.queryString(params);
   const url = `${fetchUrl}${fetchUrl.includes('?') ? '&' : '?'}${query}`;
   return get(url).then(json => {
@@ -43,6 +47,13 @@ export const queryMapReduceView = (fetchUrl, params) => {
     params.group = undefined;
     params.group_level = undefined;
   }
+  // removes params not supported by partitioned views
+  const isPartitioned = fetchUrl.includes('/_partition/');
+  if (isPartitioned) {
+    params.include_docs = undefined;
+    params.stable = undefined;
+    params.conflicts = undefined;
+  }
   const query = app.utils.queryString(params);
   const url = `${fetchUrl}${fetchUrl.includes('?') ? '&' : '?'}${query}`;
   return get(url).then(json => {
@@ -51,7 +62,8 @@ export const queryMapReduceView = (fetchUrl, params) => {
     }
     return {
       docs: json.rows,
-      docType: Constants.INDEX_RESULTS_DOC_TYPE.VIEW
+      docType: Constants.INDEX_RESULTS_DOC_TYPE.VIEW,
+      layout: isPartitioned ? Constants.LAYOUT_ORIENTATION.METADATA : undefined
     };
   });
 };
diff --git a/app/addons/documents/index-results/components/results/IndexResults.js b/app/addons/documents/index-results/components/results/IndexResults.js
index 484d3799b..01982fa45 100644
--- a/app/addons/documents/index-results/components/results/IndexResults.js
+++ b/app/addons/documents/index-results/components/results/IndexResults.js
@@ -41,11 +41,12 @@ export default class IndexResults extends React.Component {
       queryOptionsParams,
       ddocsOnly,
       fetchUrl,
-      resetState
+      resetState,
+      partitionKey
     } = nextProps;
 
     // Indicates the selected sidebar item has changed, so it needs to fetch the new list of docs
-    if (this.props.ddocsOnly !== ddocsOnly || this.props.fetchUrl !== fetchUrl) {
+    if (this.props.ddocsOnly !== ddocsOnly || this.props.fetchUrl !== fetchUrl || this.props.partitionKey !== partitionKey) {
       resetState();
       // Need to reset skip and reduce here because 'resetState()'
       // won't change props until the next update cycle
diff --git a/app/addons/documents/index-results/components/results/NoResultsScreen.js b/app/addons/documents/index-results/components/results/NoResultsScreen.js
index 0d4e8623d..c01fb01ae 100644
--- a/app/addons/documents/index-results/components/results/NoResultsScreen.js
+++ b/app/addons/documents/index-results/components/results/NoResultsScreen.js
@@ -14,11 +14,18 @@ import PropTypes from 'prop-types';
 
 import React from 'react';
 
-export default function NoResultsScreen ({ text }) {
+export default function NoResultsScreen ({ text, isWarning }) {
+  const warningMsg = (
+    <div className='no-results-screen-warning'>
+      <i className='fonticon-attention-circled'></i>
+      {text}
+    </div>
+  );
   return (
     <div className="no-results-screen">
+      {isWarning ? warningMsg : null}
       <div className="watermark-logo"></div>
-      <h3>{text}</h3>
+      {!isWarning ? <h3>{text}</h3> :  null}
     </div>
   );
 }
diff --git a/app/addons/documents/index-results/components/results/ResultsScreen.js b/app/addons/documents/index-results/components/results/ResultsScreen.js
index 86a7bb4aa..016f77cab 100644
--- a/app/addons/documents/index-results/components/results/ResultsScreen.js
+++ b/app/addons/documents/index-results/components/results/ResultsScreen.js
@@ -116,6 +116,8 @@ export default class ResultsScreen extends React.Component {
 
     if (this.props.isLoading) {
       mainView = <div className="loading-lines-wrapper"><LoadLines /></div>;
+    } else if (this.props.noResultsWarning) {
+      mainView = <NoResultsScreen text={this.props.noResultsWarning} isWarning={true}/>;
     } else if (!this.props.hasResults) {
       mainView = <NoResultsScreen text={this.props.textEmptyIndex}/>;
     } else if (this.props.selectedLayout === Constants.LAYOUT_ORIENTATION.JSON) {
diff --git a/app/addons/documents/index-results/containers/IndexResultsContainer.js b/app/addons/documents/index-results/containers/IndexResultsContainer.js
index 7914265ef..f0eca768e 100644
--- a/app/addons/documents/index-results/containers/IndexResultsContainer.js
+++ b/app/addons/documents/index-results/containers/IndexResultsContainer.js
@@ -44,6 +44,7 @@ import {
 
 const mapStateToProps = ({indexResults}, ownProps) => {
   return {
+    noResultsWarning: indexResults.noResultsWarning,
     docs: getDocs(indexResults),
     selectedDocs: getSelectedDocs(indexResults),
     isLoading: getIsLoading(indexResults),
diff --git a/app/addons/documents/index-results/reducers.js b/app/addons/documents/index-results/reducers.js
index 5d040c3b9..817ae6e15 100644
--- a/app/addons/documents/index-results/reducers.js
+++ b/app/addons/documents/index-results/reducers.js
@@ -18,6 +18,7 @@ import {getTableViewData} from './helpers/table-view';
 import {getDefaultPerPage, getDocId, isJSONDocBulkDeletable} from './helpers/shared-helpers';
 
 const initialState = {
+  noResultsWarning: '',
   docs: [],  // raw documents returned from couch
   selectedDocs: [],  // documents selected for manipulation
   isLoading: false,
@@ -94,6 +95,7 @@ export default function resultsState(state = initialState, action) {
     case ActionTypes.INDEX_RESULTS_REDUX_RESET_STATE:
       return {
         ...initialState,
+        noResultsWarning: state.noResultsWarning,
         selectedLayout: state.selectedLayout,
         selectedDocs: [],
         fetchParams: {
@@ -115,6 +117,16 @@ export default function resultsState(state = initialState, action) {
         isLoading: true
       };
 
+    case ActionTypes.INDEX_RESULTS_REDUX_PARTITION_PARAM_NOT_SUPPORTED:
+      return Object.assign({}, state, {
+        noResultsWarning: 'The selected index does not support partitions. Switch back to global mode.'
+      });
+
+    case ActionTypes.INDEX_RESULTS_REDUX_PARTITION_PARAM_MANDATORY:
+      return Object.assign({}, state, {
+        noResultsWarning: 'The selected index requires a partition key. Use the selector at the top to enter a partition key.'
+      });
+
     case ActionTypes.INDEX_RESULTS_REDUX_NEW_SELECTED_DOCS:
       return {
         ...state,
@@ -133,6 +145,7 @@ export default function resultsState(state = initialState, action) {
         ...state,
         docs: action.docs,
         isLoading: false,
+        noResultsWarning: '',
         isEditable: true, //TODO: determine logic for this
         fetchParams: Object.assign({}, state.fetchParams, action.params),
         pagination: Object.assign({}, state.pagination, {
diff --git a/app/addons/documents/layouts.js b/app/addons/documents/layouts.js
index 7f91c8e12..0d5932955 100644
--- a/app/addons/documents/layouts.js
+++ b/app/addons/documents/layouts.js
@@ -81,6 +81,7 @@ export const TabsSidebarHeader = ({
               fetchUrl={fetchUrl}
               ddocsOnly={ddocsOnly}
               queryDocs={queryDocs}
+              partitionKey={partitionKey}
               selectedNavItem={selectedNavItem} />
           </div>
           <ApiBarContainer docURL={docURL} endpoint={endpoint} endpointAddQueryOptions={endpointAddQueryOptions} />
@@ -175,7 +176,8 @@ export const DocsTabsSidebarLayout = ({
   onGlobalModeSelected,
   globalMode
 }) => {
-  let queryDocs = (params) => { return queryAllDocs(fetchUrl, params); };
+  const partitionFilter = selectedNavItem.navItem === 'all-docs' && partitionKey ? partitionKey : '';
+  let queryDocs = (params) => { return queryAllDocs(fetchUrl, partitionFilter, params); };
   if (Helpers.isViewSelected(selectedNavItem)) {
     queryDocs = (params) => { return queryMapReduceView(fetchUrl, params); };
   }
diff --git a/app/addons/documents/mango/mango.api.js b/app/addons/documents/mango/mango.api.js
index 067117225..21e5ecd20 100644
--- a/app/addons/documents/mango/mango.api.js
+++ b/app/addons/documents/mango/mango.api.js
@@ -49,7 +49,8 @@ export const fetchIndexes = (databaseName, params) => {
     }
     return {
       docs: json.indexes,
-      docType: Constants.INDEX_RESULTS_DOC_TYPE.MANGO_INDEX
+      docType: Constants.INDEX_RESULTS_DOC_TYPE.MANGO_INDEX,
+      layout: Constants.LAYOUT_ORIENTATION.JSON
     };
   });
 };
diff --git a/app/addons/documents/routes-documents.js b/app/addons/documents/routes-documents.js
index fc26dd8e7..b86cb6b60 100644
--- a/app/addons/documents/routes-documents.js
+++ b/app/addons/documents/routes-documents.js
@@ -100,8 +100,8 @@ var DocumentsRouteObject = BaseRoute.extend({
   * They are not the same when paginating
   */
   allDocs: function (databaseName, partitionKey, options) {
-    const params = this.createParams(options),
-          docParams = params.docParams;
+    const params = this.createParams(options);
+    const docParams = params.docParams;
 
     const url = FauxtonAPI.urls('allDocsSanitized', 'server', databaseName);
 
diff --git a/app/addons/documents/routes-index-editor.js b/app/addons/documents/routes-index-editor.js
index bfe9c42ba..121afb512 100644
--- a/app/addons/documents/routes-index-editor.js
+++ b/app/addons/documents/routes-index-editor.js
@@ -90,9 +90,10 @@ const IndexEditorAndResults = BaseRoute.extend({
     });
     SidebarActions.dispatchExpandSelectedItem(selectedNavItem);
 
-    const url = FauxtonAPI.urls('view', 'server', encodeURIComponent(databaseName),
+    const encodedPartKey = partitionKey ? encodeURIComponent(partitionKey) : '';
+    const url = FauxtonAPI.urls('view', 'server', encodeURIComponent(databaseName), encodedPartKey,
       encodeURIComponent(ddoc), encodeURIComponent(viewName));
-    const endpoint = FauxtonAPI.urls('view', 'apiurl', encodeURIComponent(databaseName),
+    const endpoint = FauxtonAPI.urls('view', 'apiurl', encodeURIComponent(databaseName), encodedPartKey,
       encodeURIComponent(ddoc), encodeURIComponent(viewName));
     const docURL = FauxtonAPI.constants.DOC_URLS.GENERAL;
     const navigateToPartitionedView = (partKey) => {


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services