]> source.dussan.org Git - sonarqube.git/commitdiff
unify actions dropdowns
authorStas Vilchik <vilchiks@gmail.com>
Wed, 10 Jun 2015 15:34:09 +0000 (17:34 +0200)
committerStas Vilchik <vilchiks@gmail.com>
Wed, 10 Jun 2015 15:34:20 +0000 (17:34 +0200)
26 files changed:
server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js
server/sonar-web/src/main/js/apps/coding-rules/templates/coding-rules-rule-filter-form.hbs
server/sonar-web/src/main/js/apps/issues/issue-filter-view.js
server/sonar-web/src/main/js/apps/issues/templates/issues-issue-filter-form.hbs
server/sonar-web/src/main/js/components/common/action-options-view.js [new file with mode: 0644]
server/sonar-web/src/main/js/components/issue/templates/issue-assign-form-option.hbs
server/sonar-web/src/main/js/components/issue/templates/issue-assign-form.hbs
server/sonar-web/src/main/js/components/issue/templates/issue-plan-form.hbs
server/sonar-web/src/main/js/components/issue/templates/issue-set-severity-form.hbs
server/sonar-web/src/main/js/components/issue/templates/issue-tags-form-option.hbs
server/sonar-web/src/main/js/components/issue/templates/issue-tags-form.hbs
server/sonar-web/src/main/js/components/issue/templates/issue-transitions-form.hbs
server/sonar-web/src/main/js/components/issue/views/action-options-view.js [deleted file]
server/sonar-web/src/main/js/components/issue/views/assign-form-view.js
server/sonar-web/src/main/js/components/issue/views/plan-form-view.js
server/sonar-web/src/main/js/components/issue/views/set-severity-form-view.js
server/sonar-web/src/main/js/components/issue/views/tags-form-view.js
server/sonar-web/src/main/js/components/issue/views/transitions-form-view.js
server/sonar-web/src/main/less/components/bubble-popup.less
server/sonar-web/src/main/less/components/dropdowns.less
server/sonar-web/src/main/less/components/issues.less
server/sonar-web/src/main/less/components/menu.less
server/sonar-web/src/main/less/components/search.less
server/sonar-web/src/main/less/init/icons.less
server/sonar-web/src/main/less/variables.less
server/sonar-web/src/test/js/issues-page-spec.js

index cbe6434e225411678f05007656f616a4c998bede..c0071aadc492553178979df730d8440b5e4c8910 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 define([
-  'components/issue/views/action-options-view',
+  'components/common/action-options-view',
   './templates'
 ], function (ActionOptionsView) {
   var $ = jQuery;
index 35f896c026440579733fe131e2384d139d9e26e7..e8876920f6286c661f67926ba4bb5174413df967 100644 (file)
@@ -1,38 +1,50 @@
-<h6>{{t 'coding_rules.filter_similar_rules'}}</h6>
+<header class="menu-search">
+  <h6>{{t 'coding_rules.filter_similar_rules'}}</h6>
+</header>
 
-<div class="issue-action-options">
-  <a href="#" class="issue-action-option" data-property="languages" data-value="{{lang}}">
-    {{langName}}
-  </a>
+<ul class="menu">
+  <li>
+    <a href="#" class="issue-action-option" data-property="languages" data-value="{{lang}}">
+      {{langName}}
+    </a>
+  </li>
 
   {{#if severity}}
-    <a href="#" class="issue-action-option" data-property="severities" data-value="{{severity}}">
-      {{severityHelper severity}}
-    </a>
+    <li>
+      <a href="#" class="issue-action-option" data-property="severities" data-value="{{severity}}">
+        {{severityHelper severity}}
+      </a>
+    </li>
   {{/if}}
 
   {{#if debtChar}}
-    <hr>
+    <li class="divider"></li>
 
-    <a href="#" class="issue-action-option" data-property="debt_characteristics" data-value="{{debtChar}}">
-      {{debtCharName}}
-    </a>
+    <li>
+      <a href="#" class="issue-action-option" data-property="debt_characteristics" data-value="{{debtChar}}">
+        {{debtCharName}}
+      </a>
+    </li>
 
     {{#if debtSubChar}}
-      <a href="#" class="issue-action-option" data-property="debt_characteristics" data-value="{{debtSubChar}}">
-        {{debtSubCharName}}
-      </a>
+      <li>
+        <a href="#" class="issue-action-option" data-property="debt_characteristics" data-value="{{debtSubChar}}">
+          {{debtSubCharName}}
+        </a>
+      </li>
     {{/if}}
   {{/if}}
 
   {{#notEmpty tags}}
-    <hr>
+    <li class="divider"></li>
     {{#each tags}}
-      <a href="#" class="issue-action-option" data-property="tags" data-value="{{this}}">
-        <i class="icon-tags icon-half-transparent"></i>&nbsp;{{this}}
-      </a>
+      <li>
+        <a href="#" class="issue-action-option" data-property="tags" data-value="{{this}}">
+          <i class="icon-tags icon-half-transparent"></i>&nbsp;{{this}}
+        </a>
+      </li>
     {{/each}}
   {{/notEmpty}}
-</div>
+</ul>
 
 <div class="bubble-popup-arrow"></div>
index 67f9a617d450cf949af063a894cb94c89bac9f89..28a6a86e212efab5898d45171f74861b12d5da2c 100644 (file)
@@ -1,5 +1,5 @@
 define([
-  'components/issue/views/action-options-view',
+  'components/common/action-options-view',
   './templates'
 ], function (ActionOptionsView) {
 
@@ -8,19 +8,15 @@ define([
   return ActionOptionsView.extend({
     template: Templates['issues-issue-filter-form'],
 
-    selectInitialOption: function () {
-      return this.makeActive(this.getOptions().first());
-    },
-
     selectOption: function (e) {
       var property = $(e.currentTarget).data('property'),
           value = $(e.currentTarget).data('value');
       this.trigger('select', property, value);
-      return ActionOptionsView.prototype.selectOption.apply(this, arguments);
+      this._super(e);
     },
 
     serializeData: function () {
-      return _.extend(ActionOptionsView.prototype.serializeData.apply(this, arguments), {
+      return _.extend(this._super(), {
         s: this.model.get('severity')
       });
     }
index b05052126880dfa394bbf7622466c3d13081b0b9..e9e1d0621b06e47d2d29ac3acbca78d3be3abf62 100644 (file)
@@ -1,71 +1,93 @@
-<h6>{{t "issue.filter_similar_issues"}}</h6>
+<header class="menu-search">
+  <h6>{{t "issue.filter_similar_issues"}}</h6>
+</header>
 
-<div class="issue-action-options">
-  <a href="#" class="issue-action-option" data-property="severities" data-value="{{s}}">
-    {{severityIcon severity}}&nbsp;{{t "severity" severity}}
-  </a>
-
-  <a href="#" class="issue-action-option" data-property="statuses" data-value="{{status}}">
-    {{statusIcon status}}&nbsp;{{t "issue.status" status}}
-  </a>
-
-  {{#if resolution}}
-    <a href="#" class="issue-action-option" data-property="resolutions" data-value="{{resolution}}">
-      {{t "issue.resolution" resolution}}
+<ul class="menu">
+  <li>
+    <a href="#" data-property="severities" data-value="{{s}}">
+      {{severityIcon severity}}&nbsp;{{t "severity" severity}}
     </a>
-  {{else}}
-    <a href="#" class="issue-action-option" data-property="resolved" data-value="false">
-      {{t "unresolved"}}
-    </a>
-  {{/if}}
+  </li>
 
-  {{#if assignee}}
-    <a href="#" class="issue-action-option" data-property="assignees" data-value="{{assignee}}">
-      {{t "assigned_to"}} {{assigneeName}}
+  <li>
+    <a href="#" data-property="statuses" data-value="{{status}}">
+      {{statusIcon status}}&nbsp;{{t "issue.status" status}}
     </a>
-  {{else}}
-    <a href="#" class="issue-action-option" data-property="assigned" data-value="false">
-      {{t "unassigned"}}
-    </a>
-  {{/if}}
+  </li>
 
-  {{#if actionPlan}}
-    <a href="#" class="issue-action-option" data-property="actionPlans" data-value="{{actionPlan}}">
-      {{t "issue.planned_for"}} {{actionPlanName}}
-    </a>
-  {{else}}
-    <a href="#" class="issue-action-option" data-property="planned" data-value="false">
-      {{t "issue.unplanned"}}
-    </a>
-  {{/if}}
+  <li>
+    {{#if resolution}}
+      <a href="#" data-property="resolutions" data-value="{{resolution}}">
+        {{t "issue.resolution" resolution}}
+      </a>
+    {{else}}
+      <a href="#" data-property="resolved" data-value="false">
+        {{t "unresolved"}}
+      </a>
+    {{/if}}
+  </li>
 
-  <hr>
+  <li>
+    {{#if assignee}}
+      <a href="#" data-property="assignees" data-value="{{assignee}}">
+        {{t "assigned_to"}} {{assigneeName}}
+      </a>
+    {{else}}
+      <a href="#" data-property="assigned" data-value="false">
+        {{t "unassigned"}}
+      </a>
+    {{/if}}
+  </li>
 
-  <a href="#" class="issue-action-option" data-property="rules" data-value="{{rule}}">
-    {{limitString ruleName}}
-  </a>
+  <li>
+    {{#if actionPlan}}
+      <a href="#" data-property="actionPlans" data-value="{{actionPlan}}">
+        {{t "issue.planned_for"}} {{actionPlanName}}
+      </a>
+    {{else}}
+      <a href="#" data-property="planned" data-value="false">
+        {{t "issue.unplanned"}}
+      </a>
+    {{/if}}
+  </li>
 
-  {{#each tags}}
-    <a href="#" class="issue-action-option" data-property="tags" data-value="{{this}}">
-      <i class="icon-tags icon-half-transparent"></i>&nbsp;{{this}}
+  <li class="divider"></li>
+
+  <li>
+    <a href="#" data-property="rules" data-value="{{rule}}">
+      {{limitString ruleName}}
     </a>
+  </li>
+
+  {{#each tags}}
+    <li>
+      <a href="#" data-property="tags" data-value="{{this}}">
+        <i class="icon-tags icon-half-transparent"></i>&nbsp;{{this}}
+      </a>
+    </li>
   {{/each}}
 
-  <hr>
+  <li class="divider"></li>
 
-  <a href="#" class="issue-action-option" data-property="projectUuids" data-value="{{projectUuid}}">
-    {{qualifierIcon "TRK"}}&nbsp;{{projectLongName}}
-  </a>
+  <li>
+    <a href="#" data-property="projectUuids" data-value="{{projectUuid}}">
+      {{qualifierIcon "TRK"}}&nbsp;{{projectLongName}}
+    </a>
+  </li>
 
   {{#if subProject}}
-    <a href="#" class="issue-action-option" data-property="moduleUuids" data-value="{{subProjectUuid}}">
-      {{qualifierIcon "BRC"}}&nbsp;{{subProjectLongName}}
-    </a>
+    <li>
+      <a href="#" data-property="moduleUuids" data-value="{{subProjectUuid}}">
+        {{qualifierIcon "BRC"}}&nbsp;{{subProjectLongName}}
+      </a>
+    </li>
   {{/if}}
 
-  <a href="#" class="issue-action-option" data-property="fileUuids" data-value="{{componentUuid}}">
-    {{qualifierIcon componentQualifier}}&nbsp;{{fileFromPath componentLongName}}
-  </a>
-</div>
+  <li>
+    <a href="#" data-property="fileUuids" data-value="{{componentUuid}}">
+      {{qualifierIcon componentQualifier}}&nbsp;{{fileFromPath componentLongName}}
+    </a>
+  </li>
+</ul>
 
 <div class="bubble-popup-arrow"></div>
diff --git a/server/sonar-web/src/main/js/components/common/action-options-view.js b/server/sonar-web/src/main/js/components/common/action-options-view.js
new file mode 100644 (file)
index 0000000..cf3a9b2
--- /dev/null
@@ -0,0 +1,116 @@
+define([
+  'components/common/popup'
+], function (PopupView) {
+
+  var $ = jQuery;
+
+  return PopupView.extend({
+    className: 'bubble-popup bubble-popup-menu',
+    keyScope: 'action-options',
+
+    ui: {
+      options: '.menu > li > a'
+    },
+
+    events: function () {
+      return {
+        'click @ui.options': 'selectOption',
+        'mouseenter @ui.options': 'activateOptionByPointer'
+      };
+    },
+
+    initialize: function () {
+      this.bindShortcuts();
+    },
+
+    onRender: function () {
+      PopupView.prototype.onRender.apply(this, arguments);
+      this.selectInitialOption();
+    },
+
+    getOptions: function () {
+      return this.$('.menu > li > a');
+    },
+
+    getActiveOption: function () {
+      return this.getOptions().filter('.active');
+    },
+
+    makeActive: function (option) {
+      if (option.length > 0) {
+        this.getOptions().removeClass('active').tooltip('hide');
+        option.addClass('active').tooltip('show');
+      }
+    },
+
+    selectInitialOption: function () {
+      this.makeActive(this.getOptions().first());
+    },
+
+    selectNextOption: function () {
+      this.makeActive(this.getActiveOption().parent().nextAll('li:not(.divider)').first().children('a'));
+      return false;
+    },
+
+    selectPreviousOption: function () {
+      this.makeActive(this.getActiveOption().parent().prevAll('li:not(.divider)').first().children('a'));
+      return false;
+    },
+
+    activateOptionByPointer: function (e) {
+      this.makeActive($(e.currentTarget));
+    },
+
+    bindShortcuts: function () {
+      var that = this;
+      this.currentKeyScope = key.getScope();
+      key.setScope(this.keyScope);
+      key('down', this.keyScope, function () {
+        return that.selectNextOption();
+      });
+      key('up', this.keyScope, function () {
+        return that.selectPreviousOption();
+      });
+      key('return', this.keyScope, function () {
+        return that.selectActiveOption();
+      });
+      key('escape', this.keyScope, function () {
+        return that.destroy();
+      });
+      key('backspace', this.keyScope, function () {
+        return false;
+      });
+      key('shift+tab', this.keyScope, function () {
+        return false;
+      });
+    },
+
+    unbindShortcuts: function () {
+      key.unbind('down', this.keyScope);
+      key.unbind('up', this.keyScope);
+      key.unbind('return', this.keyScope);
+      key.unbind('escape', this.keyScope);
+      key.unbind('backspace', this.keyScope);
+      key.unbind('tab', this.keyScope);
+      key.unbind('shift+tab', this.keyScope);
+      key.setScope(this.currentKeyScope);
+    },
+
+    onDestroy: function () {
+      PopupView.prototype.onDestroy.apply(this, arguments);
+      this.unbindShortcuts();
+      this.$('[data-toggle="tooltip"]').tooltip('destroy');
+      $('.tooltip').remove();
+    },
+
+    selectOption: function (e) {
+      e.preventDefault();
+      this.destroy();
+    },
+
+    selectActiveOption: function () {
+      this.getActiveOption().click();
+    }
+  });
+
+});
index e35905f8c1dc300d9a57db75296c5ad296a2bf3a..29550cde4da79cbe7ba8f74706b2fc4ffc3f1b46 100644 (file)
@@ -1,3 +1,5 @@
-<a href="#" class="issue-action-option js-issue-assignee" data-value="{{id}}" data-text="{{text}}">
-  {{text}}
-</a>
+<li>
+  <a href="#" class="js-issue-assignee" data-value="{{id}}" data-text="{{text}}">
+    {{text}}
+  </a>
+</li>
index 9d20be8d0792264a69edbaf17162669ea6f53c80..9509d7871636dbd5de7cb8f2073c01abb5c2ba19 100644 (file)
@@ -1,6 +1,10 @@
-<div class="issue-action-options">
-  <i class="icon-search issue-action-options-search-icon"></i>
-  <input class="issue-action-options-search" type="text" placeholder="Search..." value="{{query}}">
+<div class="search-box menu-search">
+  <button class="search-box-submit button-clean">
+    <i class="icon-search-new"></i>
+  </button>
+  <input class="search-box-input" type="search" placeholder="Search" value="{{query}}">
 </div>
 
+<ul class="menu"></ul>
+
 <div class="bubble-popup-arrow"></div>
index d4e693aa9d0c44739790066d55ac935c59fc9743..9184dd34b64b3145d7df5c60271765f0df83597f 100644 (file)
@@ -1,11 +1,13 @@
-<div class="issue-action-options">
+<ul class="menu">
   {{#each items}}
     {{#notEq status 'CLOSED'}}
-      <a href="#" class="issue-action-option js-issue-assignee" data-value="{{key}}" data-text="{{name}}">
-        {{name}}
-      </a>
+      <li>
+        <a href="#" class="js-issue-assignee" data-value="{{key}}" data-text="{{name}}">
+          {{name}}
+        </a>
+      </li>
     {{/notEq}}
   {{/each}}
-</div>
+</ul>
 
 <div class="bubble-popup-arrow"></div>
index 7007fddf67e2bcc42be58adfe0afab9939674254..ea6a3a92b150c3f5a0e27b196410efb4bb3a8ba9 100644 (file)
@@ -1,9 +1,11 @@
-<div class="issue-action-options">
+<ul class="menu">
   {{#each items}}
-    <a href="#" class="issue-action-option js-issue-severity" data-value="{{this}}">
-      {{severityIcon this}} {{t 'severity' this}}
-    </a>
+    <li>
+      <a href="#" class="js-issue-severity" data-value="{{this}}">
+        {{severityIcon this}} {{t 'severity' this}}
+      </a>
+    </li>
   {{/each}}
-</div>
+</ul>
 
 <div class="bubble-popup-arrow"></div>
index df054fe24666622264c75a05e59331ebfb1b821e..90df7aa6e62cf09d763c4ba29091537d3bbbf4a3 100644 (file)
@@ -1,15 +1,17 @@
-<a href="#" class="issue-action-option" data-value="{{tag}}" data-text="{{tag}}"
-   {{#if selected}}data-selected{{/if}}>
+<li>
+  <a href="#" data-value="{{tag}}" data-text="{{tag}}"
+     {{#if selected}}data-selected{{/if}}>
 
-  {{#if selected}}
-    <i class="icon-checkbox icon-checkbox-checked"></i>
-  {{else}}
-    <i class="icon-checkbox"></i>
-  {{/if}}
+    {{#if selected}}
+      <i class="icon-checkbox icon-checkbox-checked"></i>
+    {{else}}
+      <i class="icon-checkbox"></i>
+    {{/if}}
 
-  {{#if custom}}
-    + {{tag}}
-  {{else}}
-    {{tag}}
-  {{/if}}
-</a>
+    {{#if custom}}
+      + {{tag}}
+    {{else}}
+      {{tag}}
+    {{/if}}
+  </a>
+</li>
index 9d20be8d0792264a69edbaf17162669ea6f53c80..9509d7871636dbd5de7cb8f2073c01abb5c2ba19 100644 (file)
@@ -1,6 +1,10 @@
-<div class="issue-action-options">
-  <i class="icon-search issue-action-options-search-icon"></i>
-  <input class="issue-action-options-search" type="text" placeholder="Search..." value="{{query}}">
+<div class="search-box menu-search">
+  <button class="search-box-submit button-clean">
+    <i class="icon-search-new"></i>
+  </button>
+  <input class="search-box-input" type="search" placeholder="Search" value="{{query}}">
 </div>
 
+<ul class="menu"></ul>
+
 <div class="bubble-popup-arrow"></div>
index 2fa1f4cb7dd2c47e9a0d537819fcea58accb3b3b..ef8ae2f24af3608bf04171af16f4f829c0b1c4b8 100644 (file)
@@ -1,10 +1,12 @@
-<div class="issue-action-options">
+<ul class="menu">
   {{#each transitions}}
-    <a href="#" class="issue-action-option js-issue-transition" data-value="{{this}}"
-        title="{{t 'issue.transition' this 'description'}}" data-placement="right" data-toggle="tooltip">
-      {{t 'issue.transition' this}}
-    </a>
+    <li>
+      <a href="#" class="js-issue-transition" data-value="{{this}}"
+         title="{{t 'issue.transition' this 'description'}}" data-placement="right" data-container="body">
+        {{t 'issue.transition' this}}
+      </a>
+    </li>
   {{/each}}
-</div>
+</ul>
 
 <div class="bubble-popup-arrow"></div>
diff --git a/server/sonar-web/src/main/js/components/issue/views/action-options-view.js b/server/sonar-web/src/main/js/components/issue/views/action-options-view.js
deleted file mode 100644 (file)
index 57b5c95..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-define([
-  'components/common/popup'
-], function (PopupView) {
-
-  var $ = jQuery;
-
-  return PopupView.extend({
-    keyScope: 'issue-action-options',
-
-    ui: {
-      options: '.issue-action-option'
-    },
-
-    events: function () {
-      return {
-        'click .issue-action-option': 'selectOption',
-        'mouseenter .issue-action-option': 'activateOptionByPointer'
-      };
-    },
-
-    initialize: function () {
-      this.bindShortcuts();
-    },
-
-    onRender: function () {
-      PopupView.prototype.onRender.apply(this, arguments);
-      this.selectInitialOption();
-      this.$('[data-toggle="tooltip"]').tooltip({ container: 'body' });
-    },
-
-    getOptions: function () {
-      return this.$('.issue-action-option');
-    },
-
-    getActiveOption: function () {
-      return this.getOptions().filter('.active');
-    },
-
-    makeActive: function (option) {
-      if (option.length > 0) {
-        this.getOptions().removeClass('active');
-        option.addClass('active');
-      }
-    },
-
-    selectInitialOption: function () {
-      this.makeActive(this.getOptions().first());
-    },
-
-    selectNextOption: function () {
-      this.makeActive(this.getActiveOption().nextAll('.issue-action-option').first());
-      return false;
-    },
-
-    selectPreviousOption: function () {
-      this.makeActive(this.getActiveOption().prevAll('.issue-action-option').first());
-      return false;
-    },
-
-    activateOptionByPointer: function (e) {
-      this.makeActive($(e.currentTarget));
-    },
-
-    bindShortcuts: function () {
-      var that = this;
-      this.currentKeyScope = key.getScope();
-      key.setScope(this.keyScope);
-      key('down', this.keyScope, function () {
-        return that.selectNextOption();
-      });
-      key('up', this.keyScope, function () {
-        return that.selectPreviousOption();
-      });
-      key('return', this.keyScope, function () {
-        return that.selectActiveOption();
-      });
-      key('escape', this.keyScope, function () {
-        return that.destroy();
-      });
-      key('backspace', this.keyScope, function () {
-        return false;
-      });
-      key('shift+tab', this.keyScope, function () {
-        return false;
-      });
-    },
-
-    unbindShortcuts: function () {
-      key.unbind('down', this.keyScope);
-      key.unbind('up', this.keyScope);
-      key.unbind('return', this.keyScope);
-      key.unbind('escape', this.keyScope);
-      key.unbind('backspace', this.keyScope);
-      key.unbind('tab', this.keyScope);
-      key.unbind('shift+tab', this.keyScope);
-      key.setScope(this.currentKeyScope);
-    },
-
-    onDestroy: function () {
-      PopupView.prototype.onDestroy.apply(this, arguments);
-      this.unbindShortcuts();
-      this.$('[data-toggle="tooltip"]').tooltip('destroy');
-      $('.tooltip').remove();
-    },
-
-    selectOption: function (e) {
-      e.preventDefault();
-      this.destroy();
-    },
-
-    selectActiveOption: function () {
-      this.getActiveOption().click();
-    }
-  });
-
-});
index bca6a2963658f14d2667b7fbca8f832252c1348a..34123ec1d6ecfa045567594dbe504ccc34f1b2e6 100644 (file)
@@ -1,5 +1,5 @@
 define([
-  './action-options-view',
+  'components/common/action-options-view',
   '../templates'
 ], function (ActionOptionsView) {
 
@@ -18,8 +18,8 @@ define([
     },
 
     initialize: function () {
-      ActionOptionsView.prototype.initialize.apply(this, arguments);
-      this.assignees = [];
+      this._super();
+      this.assignees = null;
       this.debouncedSearch = _.debounce(this.search, 250);
     },
 
@@ -33,7 +33,7 @@ define([
 
     onRender: function () {
       var that = this;
-      ActionOptionsView.prototype.onRender.apply(this, arguments);
+      this._super();
       this.renderTags();
       setTimeout(function () {
         that.$('input').focus();
@@ -41,21 +41,22 @@ define([
     },
 
     renderTags: function () {
-      this.$('.issue-action-option').remove();
+      this.$('.menu').empty();
       this.getAssignees().forEach(this.renderAssignee, this);
+      this.bindUIElements();
       this.selectInitialOption();
     },
 
     renderAssignee: function (assignee) {
       var html = this.optionTemplate(assignee);
-      this.$('.issue-action-options').append(html);
+      this.$('.menu').append(html);
     },
 
     selectOption: function (e) {
       var assignee = $(e.currentTarget).data('value'),
           assigneeName = $(e.currentTarget).data('text');
       this.submit(assignee, assigneeName);
-      return ActionOptionsView.prototype.selectOption.apply(this, arguments);
+      return this._super(e);
     },
 
     submit: function (assignee, assigneeName) {
@@ -123,19 +124,23 @@ define([
           that.resetAssignees(data.users);
         });
       } else {
-        this.resetAssignees([]);
+        this.resetAssignees();
       }
     },
 
     resetAssignees: function (users) {
-      this.assignees = users.map(function (user) {
-        return { id: user.login, text: user.name };
-      });
+      if (users) {
+        this.assignees = users.map(function (user) {
+          return { id: user.login, text: user.name };
+        });
+      } else {
+        this.assignees = null;
+      }
       this.renderTags();
     },
 
     getAssignees: function () {
-      if (this.assignees.length > 0) {
+      if (this.assignees) {
         return this.assignees;
       }
       var assignees = [{ id: '', text: t('unassigned') }],
index 5bc566cf67dcb69a70221dc2315d4d9bda8551aa..72741a6501bba80834ab457602f92eb62fae3fbc 100644 (file)
@@ -1,5 +1,5 @@
 define([
-  './action-options-view',
+  'components/common/action-options-view',
   '../templates'
 ], function (ActionOptionsView) {
 
index 87e0cd519967b4511d721882fcf34dde55f32bb2..5595660ef036f0ba67ed774f2be6f667b8e6a342 100644 (file)
@@ -1,5 +1,5 @@
 define([
-  './action-options-view',
+  'components/common/action-options-view',
   '../templates'
 ], function (ActionOptionsView) {
 
index 868230ccd883f691259a2af3a78f51d32fb31326..a5f4e5abc92d4a57d4038561ed04297df92c6e8b 100644 (file)
@@ -1,5 +1,5 @@
 define([
-  './action-options-view',
+  'components/common/action-options-view',
   '../templates'
 ], function (ActionOptionsView) {
 
@@ -32,7 +32,7 @@ define([
 
     requestTags: function () {
       var that = this;
-      return $.get(baseUrl + '/api/issues/tags', { ps: 25 }).done(function (data) {
+      return $.get(baseUrl + '/api/issues/tags', { ps: 10 }).done(function (data) {
         that.tags = data.tags;
         that.renderTags();
       });
@@ -60,7 +60,7 @@ define([
     },
 
     renderTags: function () {
-      this.$('.issue-action-option').remove();
+      this.$('.menu').empty();
       this.filterTags(this.getTags()).forEach(this.renderSelectedTag, this);
       this.filterTags(_.difference(this.tags, this.getTags())).forEach(this.renderTag, this);
       if (this.query.length > 0 && this.tags.indexOf(this.query) === -1 && this.getTags().indexOf(this.query) === -1) {
@@ -75,7 +75,7 @@ define([
         selected: true,
         custom: false
       });
-      return this.$('.issue-action-options').append(html);
+      return this.$('.menu').append(html);
     },
 
     renderTag: function (tag) {
@@ -84,7 +84,7 @@ define([
         selected: false,
         custom: false
       });
-      return this.$('.issue-action-options').append(html);
+      return this.$('.menu').append(html);
     },
 
     renderCustomTag: function (tag) {
@@ -93,7 +93,7 @@ define([
         selected: false,
         custom: true
       });
-      return this.$('.issue-action-options').append(html);
+      return this.$('.menu').append(html);
     },
 
     selectOption: function (e) {
index 9d56b1015914e3731af87b3e9baa5916dffd9307..3fb80bbe479956388031c698e2e38fb5d8f693b4 100644 (file)
@@ -1,5 +1,5 @@
 define([
-  './action-options-view',
+  'components/common/action-options-view',
   '../templates'
 ], function (ActionOptionsView) {
 
index 947c7a84fdf4bfd4bbc08b35b112b113f7e90f53..60ca63e2b47d7e7b665b7a32c3d022a07bfc8325 100644 (file)
   box-shadow: @defaultShadow;
 }
 
+.bubble-popup-menu {
+  padding: 0;
+}
+
 .bubble-popup-arrow,
 .bubble-popup-arrow:after {
   position: absolute;
index e963838cd2611888fc1d8137137ab382124282ba..145443d0afb6c427cb4b67dcc5ba820dd2185e31 100644 (file)
@@ -45,7 +45,7 @@
   text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
   background-color: #fff;
   border: 1px solid @barBorderColor;
-  box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+  box-shadow: @defaultShadow;
   background-clip: padding-box;
 
   &.pull-right {
index 5af36fb5f2ae6ea1f61ea42c51687f3c815d3d40..e15e560b9cb9c026cbe414f2d50b53be70f421e7 100644 (file)
   white-space: nowrap;
 }
 
-.issue-action-options {
-  position: relative;
-  min-width: 120px;
-  margin: 0 -10px;
-  font-size: @smallFontSize;
-}
-
-.issue-action-option {
-  display: block;
-  padding: 3px 10px;
-}
-
-a.issue-action-option {
-  border-bottom: none;
-  color: @baseFontColor;
-
-  &.active {
-    background-color: @barBackgroundColor;
-    color: @baseFontColor;
-  }
-}
-
 input.issue-action-options-search {
   padding: 0 10px 0 30px;
   border: none;
index 37df30a50f5dfe2a6d9b35c58a95d75116124648..b805869ec173a1ab2ef49282c00beb11aa7137e1 100644 (file)
@@ -19,6 +19,8 @@
  */
 @import (reference) "../mixins";
 @import (reference) "../variables";
+@import (reference) "../init/links";
+@import (reference) "../init/type";
 @import (reference) "ui";
 
 .menu {
@@ -33,7 +35,7 @@
   > li > a,
   > li > span {
     display: block;
-    padding: 4px 20px;
+    padding: 4px 16px;
     line-height: 16px;
     clear: both;
     font-weight: normal;
@@ -42,6 +44,8 @@
 
   > li > a {
     color: @baseFontColor;
+    .link-no-underline;
+    .trans(none);
   }
 
   .divider {
   &:hover, &:focus {
     text-decoration: none;
     color: @baseFontColor;
-    background-color: @lightBlue;
+    background-color: @barBackgroundColor;
   }
 }
 
-
-.menu > .active > a {
+.menu > .active > a,
+.menu > li > a.active {
   &, &:hover, &:focus {
     color: @baseFontColor;
     text-decoration: none;
     outline: 0;
-    background-color: @lightBlue;
+    background-color: @barBackgroundColor;
   }
 }
+
+.menu-search {
+  padding: 4px 16px 0;
+
+  .search-box-input { font-size: @smallFontSize; }
+}
index 48be2ff29050c3f829ec0ebef145f2149f199d88..14bc3baf1364f31d5f893b1a5b52208346dce0d6 100644 (file)
@@ -21,4 +21,9 @@
     color: @secondFontColor;
     font-size: @iconSmallFontSize;
   }
+
+  .icon-search-new {
+    position: relative;
+    top: 1px;
+  }
 }
index 0d8a7d68c27676f4bef8ca369c324bfe0900583f..4165443ea14c7b83dd4e485611ea01e34873958f 100644 (file)
@@ -474,6 +474,14 @@ a[class^="icon-"], a[class*=" icon-"] {
   content: "\f002";
   font-size: @iconFontSize;
 }
+.icon-search-new {
+  display: inline-block;
+  vertical-align: top;
+  .square(16px);
+  background-size: 13px 14px;
+  background: no-repeat center center;
+  background-image: url('data:image/svg+xml,%3Csvg%20width%3D%2213%22%20height%3D%2214%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20stroke-linejoin%3D%22round%22%20stroke-miterlimit%3D%221.414%22%3E%3Cpath%20d%3D%22M9%206.5c0-.964-.342-1.788-1.027-2.473C7.288%203.342%206.463%203%205.5%203c-.964%200-1.788.342-2.473%201.027C2.342%204.712%202%205.537%202%206.5c0%20.964.342%201.788%201.027%202.473C3.712%209.658%204.537%2010%205.5%2010c.964%200%201.788-.342%202.473-1.027C8.658%208.288%209%207.463%209%206.5zm4%206.5c0%20.27-.1.505-.297.703-.198.198-.432.297-.703.297-.28%200-.516-.1-.703-.297l-2.68-2.672c-.932.647-1.97.97-3.117.97-.745%200-1.457-.145-2.137-.434-.68-.29-1.265-.68-1.758-1.171-.492-.493-.882-1.08-1.17-1.758C.144%207.957%200%207.245%200%206.5c0-.745.145-1.457.434-2.137.29-.68.68-1.265%201.17-1.758.494-.492%201.08-.882%201.76-1.17C4.043%201.144%204.753%201%205.5%201c.745%200%201.457.145%202.137.434.68.29%201.265.68%201.758%201.17.492.494.882%201.08%201.17%201.76.29.68.435%201.39.435%202.136%200%201.146-.323%202.185-.97%203.117l2.68%202.68c.194.193.29.427.29.703z%22%20fill%3D%22%23777%22%20fill-rule%3D%22nonzero%22%2F%3E%3C%2Fsvg%3E');
+}
 .icon-edit:before {
   content: "\f040";
   font-size: @iconFontSize;
index 6deab8de02eddde691153ceede5d5938c989b65a..9ff6b6b28ef206a52536743aa90d2b4a81dc52af 100644 (file)
  * Shadows
  */
 
-@defaultShadow: 10px 10px 20px rgba(0, 0, 0, 0.5);
+@defaultShadow: 0 6px 12px rgba(0, 0, 0, .175);
 
 
 
index 9a3df230f40dcbbf533095fae402f8696251c61d..dbbfe698475eea00547dc1b0ceeb39e2df6d271c 100644 (file)
@@ -237,16 +237,16 @@ casper.test.begin(testName('Issue Box', 'Tags'), function (test) {
       })
 
       .then(function () {
-        casper.waitForSelector('.issue-action-option[data-value=design]');
+        casper.waitForSelector('a[data-value=design]');
       })
 
       .then(function () {
-        casper.click('.issue-action-option[data-value=design]');
+        casper.click('a[data-value=design]');
         test.assertSelectorContains('.issue.selected .js-issue-tags', 'security, cwe, design');
       })
 
       .then(function () {
-        casper.click('.issue-action-option[data-value=cwe]');
+        casper.click('a[data-value=cwe]');
         test.assertSelectorContains('.issue.selected .js-issue-tags', 'security, design');
       })
 
@@ -284,13 +284,13 @@ casper.test.begin(testName('Issue Box', 'Transitions'), function (test) {
 
       .then(function () {
         casper.click('.issue.selected .js-issue-transition');
-        casper.waitForSelector('.issue-action-option');
+        casper.waitForSelector('.menu > li > a');
       })
 
       .then(function () {
-        test.assertExists('.issue-action-option[data-value=unconfirm]');
-        test.assertExists('.issue-action-option[data-value=resolve]');
-        test.assertExists('.issue-action-option[data-value=falsepositive]');
+        test.assertExists('a[data-value=unconfirm]');
+        test.assertExists('a[data-value=resolve]');
+        test.assertExists('a[data-value=falsepositive]');
       })
 
       .then(function () {