]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8374 Make the "Me" option more visible on the "Issues" page
authorStas Vilchik <vilchiks@gmail.com>
Wed, 9 Nov 2016 13:03:23 +0000 (14:03 +0100)
committerStas Vilchik <vilchiks@gmail.com>
Thu, 10 Nov 2016 12:23:45 +0000 (13:23 +0100)
13 files changed:
server/sonar-web/src/main/js/apps/component-issues/app.js
server/sonar-web/src/main/js/apps/issues/HeaderView.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/issues/app.js
server/sonar-web/src/main/js/apps/issues/controller.js
server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js
server/sonar-web/src/main/js/apps/issues/facets/mode-facet.js
server/sonar-web/src/main/js/apps/issues/layout.js
server/sonar-web/src/main/js/apps/issues/styles.css [new file with mode: 0644]
server/sonar-web/src/main/js/apps/issues/templates/facets/issues-assignee-facet.hbs
server/sonar-web/src/main/js/apps/issues/templates/facets/issues-mode-facet.hbs
server/sonar-web/src/main/js/apps/issues/templates/facets/issues-my-issues-facet.hbs [new file with mode: 0644]
server/sonar-web/src/main/js/apps/issues/templates/issues-layout.hbs
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 7768330dd439660bb2c37f95a5a9678212a7bc72..7397e84eed97853544c2082dd707a5831215ffbd 100644 (file)
@@ -30,6 +30,7 @@ import Router from '../issues/router';
 import WorkspaceListView from '../issues/workspace-list-view';
 import WorkspaceHeaderView from '../issues/workspace-header-view';
 import FacetsView from './../issues/facets-view';
+import HeaderView from './../issues/HeaderView';
 
 const App = new Marionette.Application();
 const init = function () {
@@ -73,6 +74,11 @@ const init = function () {
   });
   this.layout.facetsRegion.show(this.facetsView);
 
+  this.headerView = new HeaderView({
+    app: this
+  });
+  this.layout.filtersRegion.show(this.headerView);
+
   key.setScope('list');
   App.router = new Router({ app: App });
   Backbone.history.start();
diff --git a/server/sonar-web/src/main/js/apps/issues/HeaderView.js b/server/sonar-web/src/main/js/apps/issues/HeaderView.js
new file mode 100644 (file)
index 0000000..01d6e6c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import Marionette from 'backbone.marionette';
+import Template from './templates/facets/issues-my-issues-facet.hbs';
+
+export default Marionette.ItemView.extend({
+  template: Template,
+  className: 'issues-header-inner',
+
+  events: {
+    'change [name="issues-page-my"]': 'onMyIssuesChange'
+  },
+
+  initialize () {
+    this.listenTo(this.options.app.state, 'change:query', this.render);
+  },
+
+  onMyIssuesChange () {
+    const mode = this.$('[name="issues-page-my"]:checked').val();
+    if (mode === 'my') {
+      this.options.app.state.updateFilter({
+        assigned_to_me: 'true',
+        assignees: null,
+        assigned: null
+      });
+    } else {
+      this.options.app.state.updateFilter({
+        assigned_to_me: null,
+        assignees: null,
+        assigned: null
+      });
+    }
+  },
+  serializeData () {
+    const me = !!this.options.app.state.get('query').assigned_to_me;
+    return {
+      ...Marionette.ItemView.prototype.serializeData.apply(this, arguments),
+      me,
+      isContext: this.options.app.state.get('isContext'),
+      user: window.SS.user
+    };
+  }
+});
+
index bc083906618319e85b9a7f346fc66b1edadb1125..4623b55988ff665223abe7e679580bd28f2fd1e4 100644 (file)
@@ -29,6 +29,7 @@ import Router from './router';
 import WorkspaceListView from './workspace-list-view';
 import WorkspaceHeaderView from './workspace-header-view';
 import FacetsView from './facets-view';
+import HeaderView from './HeaderView';
 
 const App = new Marionette.Application();
 const init = function () {
@@ -63,6 +64,11 @@ const init = function () {
   });
   this.layout.facetsRegion.show(this.facetsView);
 
+  this.headerView = new HeaderView({
+    app: this
+  });
+  this.layout.filtersRegion.show(this.headerView);
+
   key.setScope('list');
   App.router = new Router({ app: App });
   Backbone.history.start();
index aa5d45d3d0015b2e362bab4d120069196152a4c3..11512cd4c48f38001fa4dcd3a179b93048b43c77 100644 (file)
@@ -26,14 +26,6 @@ import ComponentViewer from './component-viewer/main';
 const FACET_DATA_FIELDS = ['components', 'users', 'rules', 'languages'];
 
 export default Controller.extend({
-  _facetsFromServer () {
-    const facets = Controller.prototype._facetsFromServer.apply(this, arguments) || [];
-    if (facets.indexOf('assignees') !== -1) {
-      facets.push('assigned_to_me');
-    }
-    return facets;
-  },
-
   _issuesParameters () {
     return {
       p: this.options.app.state.get('page'),
@@ -45,15 +37,6 @@ export default Controller.extend({
     };
   },
 
-  _myIssuesFromResponse (r) {
-    const myIssuesData = _.findWhere(r.facets, { property: 'assigned_to_me' });
-    if ((myIssuesData != null) && _.isArray(myIssuesData.values) && myIssuesData.values.length > 0) {
-      return this.options.app.state.set({ myIssues: myIssuesData.values[0].count }, { silent: true });
-    } else {
-      return this.options.app.state.unset('myIssues', { silent: true });
-    }
-  },
-
   fetchList (firstPage) {
     const that = this;
     if (firstPage == null) {
@@ -65,6 +48,9 @@ export default Controller.extend({
     }
     const data = this._issuesParameters();
     _.extend(data, this.options.app.state.get('query'));
+    if (this.options.app.state.get('query').assigned_to_me) {
+      _.extend(data, { assignees: '__me__' });
+    }
     if (this.options.app.state.get('isContext')) {
       _.extend(data, this.options.app.state.get('contextQuery'));
     }
@@ -80,10 +66,7 @@ export default Controller.extend({
         that.options.app.facets[field] = r[field];
       });
       that.options.app.facets.reset(that._allFacets());
-      that.options.app.facets.add(_.reject(r.facets, function (f) {
-        return f.property === 'assigned_to_me';
-      }), { merge: true });
-      that._myIssuesFromResponse(r);
+      that.options.app.facets.add(r.facets, { merge: true });
       that.enableFacets(that._enabledFacets());
       if (firstPage) {
         that.options.app.state.set({
@@ -117,9 +100,6 @@ export default Controller.extend({
 
   requestFacet (id) {
     const that = this;
-    if (id === 'assignees') {
-      return this.requestAssigneeFacet();
-    }
     const facet = this.options.app.facets.get(id);
     const data = _.extend({ facets: id, ps: 1, additionalFields: '_all' }, this.options.app.state.get('query'));
     if (this.options.app.state.get('isContext')) {
@@ -136,26 +116,6 @@ export default Controller.extend({
     });
   },
 
-  requestAssigneeFacet () {
-    const that = this;
-    const facet = this.options.app.facets.get('assignees');
-    const data = _.extend({ facets: 'assignees,assigned_to_me', ps: 1, additionalFields: '_all' },
-        this.options.app.state.get('query'));
-    if (this.options.app.state.get('isContext')) {
-      _.extend(data, this.options.app.state.get('contextQuery'));
-    }
-    return $.get(window.baseUrl + '/api/issues/search', data, function (r) {
-      FACET_DATA_FIELDS.forEach(function (field) {
-        that.options.app.facets[field] = that._mergeCollections(that.options.app.facets[field], r[field]);
-      });
-      const facetData = _.findWhere(r.facets, { property: 'assignees' });
-      that._myIssuesFromResponse(r);
-      if (facetData != null) {
-        return facet.set(facetData);
-      }
-    });
-  },
-
   newSearch () {
     this.options.app.state.unset('filter');
     return this.options.app.state.setQuery({ resolved: 'false' });
index f67204b3278de92a0e66bad0c6a3a44ab6aaf39c..bea677a429011eb6da9a8b557e940d95eb4bfe28 100644 (file)
@@ -56,12 +56,14 @@ export default CustomValuesFacet.extend({
       const value = checked ? 'false' : null;
       return this.options.app.state.updateFilter({
         assigned: value,
-        assignees: null
+        assignees: null,
+        assigned_to_me: null
       });
     } else {
       return this.options.app.state.updateFilter({
         assigned: null,
-        assignees: this.getValue()
+        assignees: this.getValue(),
+        assigned_to_me: null
       });
     }
   },
@@ -110,13 +112,8 @@ export default CustomValuesFacet.extend({
     });
   },
 
-  getNumberOfMyIssues () {
-    return this.options.app.state.get('myIssues');
-  },
-
   serializeData () {
     return _.extend(CustomValuesFacet.prototype.serializeData.apply(this, arguments), {
-      myIssues: this.getNumberOfMyIssues(),
       values: this.sortValues(this.getValuesWithLabels())
     });
   }
index 5b4ca34ced76928382081cb3b79811a1b6764009..8612111c2e40a307d488eb546bf58f0c384625f9 100644 (file)
@@ -17,6 +17,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
+import $ from 'jquery';
 import _ from 'underscore';
 import BaseFacet from './base-facet';
 import Template from '../templates/facets/issues-mode-facet.hbs';
@@ -24,13 +25,11 @@ import Template from '../templates/facets/issues-mode-facet.hbs';
 export default BaseFacet.extend({
   template: Template,
 
-  events: {
-    'change [name="issues-page-mode"]': 'onModeChange'
-  },
-
-  onModeChange () {
-    const mode = this.$('[name="issues-page-mode"]:checked').val();
-    this.options.app.state.updateFilter({ facetMode: mode });
+  toggleFacet (e) {
+    const isCount = $(e.currentTarget).is('[data-value="count"]');
+    return this.options.app.state.updateFilter({
+      facetMode: isCount ? 'count' : 'effort'
+    });
   },
 
   serializeData () {
index 1b36f36c231fad113e15df95966aed201c8ef308..3eeb76f018886894070c1c6f932b4b4f206c9d9e 100644 (file)
@@ -21,12 +21,13 @@ import $ from 'jquery';
 import _ from 'underscore';
 import Marionette from 'backbone.marionette';
 import Template from './templates/issues-layout.hbs';
+import './styles.css';
 
 export default Marionette.LayoutView.extend({
   template: Template,
 
   regions: {
-    filtersRegion: '.search-navigator-filters',
+    filtersRegion: '.issues-header',
     facetsRegion: '.search-navigator-facets',
     workspaceHeaderRegion: '.search-navigator-workspace-header',
     workspaceListRegion: '.search-navigator-workspace-list',
@@ -34,9 +35,6 @@ export default Marionette.LayoutView.extend({
   },
 
   onRender () {
-    if (this.options.app.state.get('isContext')) {
-      this.$(this.filtersRegion.el).addClass('hidden');
-    }
     this.$('.search-navigator').addClass('sticky');
     const top = this.$('.search-navigator').offset().top;
     this.$('.search-navigator-workspace-header').css({ top });
diff --git a/server/sonar-web/src/main/js/apps/issues/styles.css b/server/sonar-web/src/main/js/apps/issues/styles.css
new file mode 100644 (file)
index 0000000..5534dc2
--- /dev/null
@@ -0,0 +1,16 @@
+.issues-header-inner {
+  padding: 32px 10px 15px;
+  background-color: #f3f3f3;
+  text-align: center;
+}
+
+.issues-header-inner:empty {
+  display: none;
+}
+
+.issues-header-order {
+  display: inline-block;
+  vertical-align: top;
+  margin-right: 20px;
+  font-size: 12px;
+}
index 4121c2eee5ce424ba48c5e89ee39b898b49c306a..9fb23f78ab8dc7609360607147b74c5c490f069f 100644 (file)
@@ -1,16 +1,6 @@
 {{> "_issues-facet-header"}}
 
 <div class="search-navigator-facet-list">
-  {{#notNull myIssues}}
-    <a class="facet search-navigator-facet js-facet" data-value="__me__" title="{{t "me"}}">
-      <span class="facet-name">{{t "me"}}</span>
-      <span class="facet-stat">
-        {{formatFacetValue myIssues state.facetMode}}
-      </span>
-    </a>
-    <hr>
-  {{/notNull}}
-
   {{#each values}}
     {{#eq val ""}}
     {{! unassigned }}
index 26dc6a0a5abc26595153ea5dbfdefb8b06987e59..af69286d92af8a1ad2fed2467feaf1f49b90203d 100644 (file)
@@ -1,14 +1,15 @@
-<div class="issues-facet-mode">
-  <ul class="radio-toggle">
-    <li>
-      <input type="radio" name="issues-page-mode" value="count" id="issues-page-mode-count"
-             {{#eq mode 'count'}}checked{{/eq}}>
-      <label for="issues-page-mode-count">{{t 'issues.facet.mode.issues'}}</label>
-    </li>
-    <li>
-      <input type="radio" name="issues-page-mode" value="effort" id="issues-page-mode-effort"
-             {{#eq mode 'effort'}}checked{{/eq}}>
-      <label for="issues-page-mode-effort">{{t 'issues.facet.mode.effort'}}</label>
-    </li>
-  </ul>
+<div class="search-navigator-facet-header">
+  {{t 'issues.facet.mode'}}
+</div>
+
+
+<div class="search-navigator-facet-list">
+  <a class="facet search-navigator-facet search-navigator-facet-half js-facet {{#eq mode 'count'}}active{{/eq}}"
+     data-value="count">
+    <span class="facet-name">{{t 'issues.facet.mode.issues'}}</span>
+  </a>
+  <a class="facet search-navigator-facet search-navigator-facet-half js-facet {{#eq mode 'effort'}}active{{/eq}}"
+     data-value="effort">
+    <span class="facet-name">{{t 'issues.facet.mode.effort'}}</span>
+  </a>
 </div>
diff --git a/server/sonar-web/src/main/js/apps/issues/templates/facets/issues-my-issues-facet.hbs b/server/sonar-web/src/main/js/apps/issues/templates/facets/issues-my-issues-facet.hbs
new file mode 100644 (file)
index 0000000..ce38e1f
--- /dev/null
@@ -0,0 +1,12 @@
+{{#if user}}
+  <ul class="radio-toggle">
+    <li>
+      <input type="radio" name="issues-page-my" value="my" id="issues-page-my-my" {{#if me}}checked{{/if}}>
+      <label for="issues-page-my-my">My Issues</label>
+    </li>
+    <li>
+      <input type="radio" name="issues-page-my" value="all" id="issues-page-my-all" {{#unless me}}checked{{/unless}}>
+      <label for="issues-page-my-all">All</label>
+    </li>
+  </ul>
+{{/if}}
index 393845b0394e006243d4386a7bdf95f779e7c69b..83add61b3660bcf038baeba1bf9bd469e099026b 100644 (file)
@@ -1,8 +1,6 @@
 <div class="issues search-navigator">
   <div class="search-navigator-side">
-    <div class="search-navigator-filters">
-      <h1 class="page-title">{{t "issues"}}</h1>
-    </div>
+    <div class="issues-header"></div>
     <div class="search-navigator-facets"></div>
   </div>
 
index 7fd2e16ce66d9c12be82bbf08cf16641bcecfb88..51f921747041e98222a40991c0f42f5f76a74b18 100644 (file)
@@ -773,6 +773,7 @@ issues.facet.createdAt.last_month=Last month
 issues.facet.createdAt.last_year=Last year
 issues.facet.authors=Author
 issues.facet.issues=Issue Key
+issues.facet.mode=Display Mode
 issues.facet.mode.issues=Issues
 issues.facet.mode.effort=Effort