Update URL generation for groups

This change brings router abstraction to the group views (details,
members and audit log). The app params for these views are refactored to
use `Gerrit.Nav.View.GROUP` rather than `Gerrit.Nav.View.ADMIN`.

Change-Id: Ifa3e19c509c7f2f72e34bb05279bb3a45057cf2d
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.html b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.html
index efacb1e..9fe10bc 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.html
@@ -20,6 +20,7 @@
 <link rel="import" href="../../../bower_components/iron-input/iron-input.html">
 <link rel="import" href="../../../styles/gr-table-styles.html">
 <link rel="import" href="../../../styles/shared-styles.html">
+<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
 <link rel="import" href="../../shared/gr-confirm-dialog/gr-confirm-dialog.html">
 <link rel="import" href="../../shared/gr-list-view/gr-list-view.html">
 <link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.js b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.js
index 72439e2..e4f5647 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.js
+++ b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.js
@@ -93,7 +93,7 @@
     },
 
     _computeGroupUrl(id) {
-      return this.getUrl(this._path + '/', id);
+      return Gerrit.Nav.getUrlForGroup(id);
     },
 
     _getCreateGroupCapability() {
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
index 951df45..86b1ae4 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
@@ -21,6 +21,7 @@
 <link rel="import" href="../../../styles/gr-menu-page-styles.html">
 <link rel="import" href="../../../styles/gr-page-nav-styles.html">
 <link rel="import" href="../../../styles/shared-styles.html">
+<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
 <link rel="import" href="../../shared/gr-page-nav/gr-page-nav.html">
 <link rel="import" href="../../shared/gr-placeholder/gr-placeholder.html">
 <link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
index ae28a05..9848775 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
@@ -148,14 +148,13 @@
           linkCopy.subsection = {
             name: this._groupName,
             view: 'gr-group',
-            url: `/admin/groups/${this.encodeURL(this._groupId + '', true)}`,
+            url: Gerrit.Nav.getUrlForGroup(this._groupId),
             children: [
               {
                 name: 'Members',
                 detailType: 'members',
                 view: 'gr-group-members',
-                url: `/admin/groups/${this.encodeURL(this._groupId, true)}` +
-                    ',members',
+                url: Gerrit.Nav.getUrlForGroupMembers(this._groupId),
               },
             ],
           };
@@ -165,8 +164,7 @@
                   name: 'Audit Log',
                   detailType: 'audit-log',
                   view: 'gr-group-audit-log',
-                  url: '/admin/groups/' +
-                      `${this.encodeURL(this._groupId + '', true)},audit-log`,
+                  url: Gerrit.Nav.getUrlForGroupLog(this._groupId),
                 }
             );
           }
@@ -187,19 +185,31 @@
     },
 
     _paramsChanged(params) {
-      this.set('_showGroup', params.adminView === 'gr-group');
-      this.set('_showGroupAuditLog', params.adminView === 'gr-group-audit-log');
-      this.set('_showGroupList', params.adminView === 'gr-admin-group-list');
-      this.set('_showGroupMembers', params.adminView === 'gr-group-members');
-      this.set('_showProjectCommands',
+      const isGroupView = params.view === Gerrit.Nav.View.GROUP;
+      const isAdminView = params.view === Gerrit.Nav.View.ADMIN;
+
+      this.set('_showGroup', isGroupView && !params.detail);
+      this.set('_showGroupAuditLog', isGroupView &&
+          params.detail === Gerrit.Nav.GroupDetailView.LOG);
+      this.set('_showGroupMembers', isGroupView &&
+          params.detail === Gerrit.Nav.GroupDetailView.MEMBERS);
+
+      this.set('_showGroupList', isAdminView &&
+          params.adminView === 'gr-admin-group-list');
+
+      this.set('_showProjectCommands', isAdminView &&
           params.adminView === 'gr-project-commands');
-      this.set('_showProjectMain', params.adminView === 'gr-project');
-      this.set('_showProjectList',
+      this.set('_showProjectMain', isAdminView &&
+          params.adminView === 'gr-project');
+      this.set('_showProjectList', isAdminView &&
           params.adminView === 'gr-project-list');
-      this.set('_showProjectDetailList',
+      this.set('_showProjectDetailList', isAdminView &&
           params.adminView === 'gr-project-detail-list');
-      this.set('_showPluginList', params.adminView === 'gr-plugin-list');
-      this.set('_showProjectAccess', params.adminView === 'gr-project-access');
+      this.set('_showPluginList', isAdminView &&
+          params.adminView === 'gr-plugin-list');
+      this.set('_showProjectAccess', isAdminView &&
+          params.adminView === 'gr-project-access');
+
       if (params.project !== this._projectName) {
         this._projectName = params.project || '';
         // Reloads the admin menu.
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
index 117940a3..62c4ed6 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
@@ -75,6 +75,7 @@
       }];
 
       element.params = {
+        view: 'admin',
         adminView: 'gr-project-list',
       };
 
@@ -206,7 +207,7 @@
         assert.isTrue(element.reload.called);
         done();
       });
-      element.params = {group: 1, adminView: 'gr-group'};
+      element.params = {group: 1, view: Gerrit.Nav.View.GROUP};
       element._groupName = 'oldName';
       flushAsynchronousOperations();
       element.$$('gr-group').fire('name-changed', {name: newName});
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
index 8453da9..6ff78d8 100644
--- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
+++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
@@ -47,6 +47,11 @@
     //    - `leftSide`, optional, Boolean, if a `lineNum` is provided, a value
     //        of true selects the line from base of the patch range. False by
     //        default.
+    //
+    //  - Gerrit.Nav.View.GROUP:
+    //    - `groupId`, required, String, the ID of the group.
+    //    - `detail`, optional, String, the name of the group detail view.
+    //      Takes any value from Gerrit.Nav.GroupDetailView.
 
     window.Gerrit = window.Gerrit || {};
 
@@ -71,6 +76,12 @@
         EDIT: 'edit',
         SEARCH: 'search',
         SETTINGS: 'settings',
+        GROUP: 'group',
+      },
+
+      GroupDetailView: {
+        MEMBERS: 'members',
+        LOG: 'log',
       },
 
       /** @type {Function} */
@@ -315,6 +326,41 @@
         }
         this._navigate(relativeUrl);
       },
+
+      /**
+       * @param {string} groupId
+       * @return {string}
+       */
+      getUrlForGroup(groupId) {
+        return this._getUrlFor({
+          view: Gerrit.Nav.View.GROUP,
+          groupId,
+        });
+      },
+
+      /**
+       * @param {string} groupId
+       * @return {string}
+       */
+      getUrlForGroupLog(groupId) {
+        return this._getUrlFor({
+          view: Gerrit.Nav.View.GROUP,
+          groupId,
+          detail: Gerrit.Nav.GroupDetailView.LOG,
+        });
+      },
+
+      /**
+       * @param {string} groupId
+       * @return {string}
+       */
+      getUrlForGroupMembers(groupId) {
+        return this._getUrlFor({
+          view: Gerrit.Nav.View.GROUP,
+          groupId,
+          detail: Gerrit.Nav.GroupDetailView.MEMBERS,
+        });
+      },
     };
   })(window);
 </script>
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.js b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
index c0b8941..ccf0055 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.js
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
@@ -204,6 +204,8 @@
         url = this._generateDashboardUrl(params);
       } else if (params.view === Views.DIFF || params.view === Views.EDIT) {
         url = this._generateDiffOrEditUrl(params);
+      } else if (params.view === Views.GROUP) {
+        url = this._generateGroupUrl(params);
       } else {
         throw new Error('Can\'t generate');
       }
@@ -314,6 +316,20 @@
     },
 
     /**
+     * @param {!Object} params
+     * @return {string}
+     */
+    _generateGroupUrl(params) {
+      let url = `/admin/groups/${this.encodeURL(params.groupId + '', true)}`;
+      if (params.detail === Gerrit.Nav.GroupDetailView.MEMBERS) {
+        url += ',members';
+      } else if (params.detail === Gerrit.Nav.GroupDetailView.LOG) {
+        url += ',audit-log';
+      }
+      return url;
+    },
+
+    /**
      * Given an object of parameters, potentially including a `patchNum` or a
      * `basePatchNum` or both, return a string representation of that range. If
      * no range is indicated in the params, the empty string is returned.
@@ -765,20 +781,25 @@
       this._redirect('/admin/groups/' + encodeURIComponent(data.params[0]));
     },
 
+    _handleGroupRoute(data) {
+      this._setParams({
+        view: Gerrit.Nav.View.GROUP,
+        groupId: data.params[0],
+      });
+    },
+
     _handleGroupAuditLogRoute(data) {
       this._setParams({
-        view: Gerrit.Nav.View.ADMIN,
-        adminView: 'gr-group-audit-log',
-        detailType: 'audit-log',
+        view: Gerrit.Nav.View.GROUP,
+        detail: Gerrit.Nav.GroupDetailView.LOG,
         groupId: data.params[0],
       });
     },
 
     _handleGroupMembersRoute(data) {
       this._setParams({
-        view: Gerrit.Nav.View.ADMIN,
-        adminView: 'gr-group-members',
-        detailType: 'members',
+        view: Gerrit.Nav.View.GROUP,
+        detail: Gerrit.Nav.GroupDetailView.MEMBERS,
         groupId: data.params[0],
       });
     },
@@ -810,14 +831,6 @@
       });
     },
 
-    _handleGroupRoute(data) {
-      this._setParams({
-        view: Gerrit.Nav.View.ADMIN,
-        adminView: 'gr-group',
-        groupId: data.params[0],
-      });
-    },
-
     _handleProjectCommandsRoute(data) {
       this._setParams({
         view: Gerrit.Nav.View.ADMIN,
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
index b4fec5b..03b6bf2 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
@@ -365,6 +365,36 @@
               '/dashboard/user?name=query&title=custom%20dashboard');
         });
       });
+
+      suite('groups', () => {
+        test('group info', () => {
+          const params = {
+            view: Gerrit.Nav.View.GROUP,
+            groupId: 1234,
+          };
+          assert.equal(element._generateUrl(params), '/admin/groups/1234');
+        });
+
+        test('group members', () => {
+          const params = {
+            view: Gerrit.Nav.View.GROUP,
+            groupId: 1234,
+            detail: 'members',
+          };
+          assert.equal(element._generateUrl(params),
+              '/admin/groups/1234,members');
+        });
+
+        test('group audit log', () => {
+          const params = {
+            view: Gerrit.Nav.View.GROUP,
+            groupId: 1234,
+            detail: 'log',
+          };
+          assert.equal(element._generateUrl(params),
+              '/admin/groups/1234,audit-log');
+        });
+      });
     });
 
     suite('param normalization', () => {
@@ -804,9 +834,8 @@
         test('_handleGroupAuditLogRoute', () => {
           const data = {params: {0: 1234}};
           assertDataToParams(data, '_handleGroupAuditLogRoute', {
-            view: Gerrit.Nav.View.ADMIN,
-            adminView: 'gr-group-audit-log',
-            detailType: 'audit-log',
+            view: Gerrit.Nav.View.GROUP,
+            detail: 'log',
             groupId: 1234,
           });
         });
@@ -814,9 +843,8 @@
         test('_handleGroupMembersRoute', () => {
           const data = {params: {0: 1234}};
           assertDataToParams(data, '_handleGroupMembersRoute', {
-            view: Gerrit.Nav.View.ADMIN,
-            adminView: 'gr-group-members',
-            detailType: 'members',
+            view: Gerrit.Nav.View.GROUP,
+            detail: 'members',
             groupId: 1234,
           });
         });
@@ -872,8 +900,7 @@
         test('_handleGroupRoute', () => {
           const data = {params: {0: 4321}};
           assertDataToParams(data, '_handleGroupRoute', {
-            view: Gerrit.Nav.View.ADMIN,
-            adminView: 'gr-group',
+            view: Gerrit.Nav.View.GROUP,
             groupId: 4321,
           });
         });
diff --git a/polygerrit-ui/app/elements/gr-app.js b/polygerrit-ui/app/elements/gr-app.js
index 8da8e16..3e75d40 100644
--- a/polygerrit-ui/app/elements/gr-app.js
+++ b/polygerrit-ui/app/elements/gr-app.js
@@ -138,7 +138,8 @@
       this.set('_showChangeView', view === Gerrit.Nav.View.CHANGE);
       this.set('_showDiffView', view === Gerrit.Nav.View.DIFF);
       this.set('_showSettingsView', view === Gerrit.Nav.View.SETTINGS);
-      this.set('_showAdminView', view === Gerrit.Nav.View.ADMIN);
+      this.set('_showAdminView', view === Gerrit.Nav.View.ADMIN ||
+          view === Gerrit.Nav.View.GROUP);
       this.set('_showCLAView', view === Gerrit.Nav.View.AGREEMENTS);
       this.set('_showEditorView', view === Gerrit.Nav.View.EDIT);
       if (this.params.justRegistered) {